|
6. Getting the images out of the mp3 files
The trickiest part of the job was getting the images. Since
the images are not in the XML file we need to get them out
of the mp3 files themselves. iTunes uses the correct mp3 v2
tag to store the image. Now, initially I wrote a perl
script to extract the images based on a perl module. But,
you need to install the perl modules MP3::Info and URI::URL
in order for this to work. This is not too hard to do, but
is still some effort. I could have packaged the perl
modules I guess, but I found it easier to create a little
Cocoa command line tool that does the same based on
libid3,
the library that is distributed by http://www.id3.org.
Both approaches are
still explained however.
Using a custom command line tool to get the image out of the mp3 file
Another approach is taken in the downloadable package however. The getPicure
command is not a perl command, but a compiled tool, based on id3v2 which already
uses the libid3 library and has a great set of functionalities, except... extracting
images.
Adapting the sources to eliminate all we don't need and adding the extra little bit
of functionality to extract the image was easy however, since we basically know
how to do this in perl already. In order to compile it you will need to have the
libid3 headers in place and have a libid3 library that you can link to. The commands
needed to compile it with the statically linked library are included in comments
in the source code.
Code listing 6.1: Source code to getPicture command line tool |
/**
* Based on id3v2 ... compile something like
*
* g++ -I/usr/local/include/ -O3 -c -o getpic.o getpic.cpp
* c++ -L/usr/local/lib/ -O3 -pedantic -Wall -framework CoreFoundation -lz -liconv
* -g -o id3v2 getpic.o ./libid3.a
*
* Part of CCTunes, distributed under the GPL.
* details at http://www.coin-c.com/CCTunes/
*/
#include <CoreFoundation/CoreFoundation.h>
#include <id3/misc_support.h>
#include <id3/tag.h>
#include "frametable.h"
#include "genre.h"
int main( int argc, char *argv[]);
int main( int argc, char *argv[])
{
bool tags = false;
CFURLRef theSourceUrl = CFURLCreateWithBytes(kCFAllocatorDefault,
(unsigned char*)argv[1],
strlen(argv[1]),
kCFStringEncodingUTF8,
NULL);
unsigned char sourceFilePath[500];
if (CFURLGetFileSystemRepresentation(theSourceUrl,true,sourceFilePath,500))
{
ID3_Tag myTag;
myTag.Link((char*)sourceFilePath, ID3TT_ID3V2);
const ID3_Frame * myFrame = 0;
const ID3_Tag myTagConstRef = myTag;
ID3_Tag::ConstIterator *Iter = myTagConstRef.CreateIterator();
for (size_t nFrames = 0; nFrames < myTag.NumFrames(); nFrames++)
{
myFrame = Iter->GetNext();
if (NULL != myFrame && myFrame->GetID() == ID3FID_PICTURE)
{
myFrame->Field(ID3FN_DATA).ToFile(argv[2]);
tags = true;
break;
}
}
}
if(!tags)
std::cout << "<warning><id>no_picture</id><info>" << (unsigned char*)argv[1]
<< "</info></warning>" << std::endl;
}
|
Generating Thumbnails
This might be all you need if you are on your own private server, have lots of
disk space and don't really care on how fast your collection loads in the browser.
Since I have been using this, I found that the size of the images tends to be too
big to view all of the images for all of the albums at once, so it would be
nice to generate thumbnails for the overview.
However, for your ease of use, the currently downloadable package comes with a little
command line tool programmed in cocoa and based on
pdf2png by Evan Jones which does all of this for you. It simply takes an image
and draws it in an offline buffer of the specified size and saves that as a png
file. I must say however, you will see that the quality is not good. It is
the same quality you can see if you use iPhoto to look at the images you've
taken with your digital camera. Uuuugly. I must provide some feedback to Apple on that
someday.
Code listing 6.2: Little Cocoa command line tool to resize images, based on pdf2png |
// A tiny program that resizes images to PNG images with certain dimensions.
// based on pdf2png by Evan Jones, http://evanjones.ca/pdf2png.m
// modified by Kristof Van Landschoot, Coin-C to fit the purpose of resizing.
//
// gcc --std=c99 -g -o resize resize.m -framework Cocoa
//
// Written originally by Evan Jones <ejones@uwaterloo.ca> Februrary, 2004
// http://www.eng.uwaterloo.ca/~ejones/
//
// Released under the GNU Public License
#include <Cocoa/Cocoa.h>
int main( int argc, char* argv[] )
{
int destinationSize = 36; // in DPI
int page = 1;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Package all arguments as NSStrings in an NSArray
NSMutableArray* args = [NSMutableArray arrayWithCapacity: argc - 1];
for ( int i = 1; i < argc; ++ i )
{
[args addObject: [NSString stringWithCString: argv[i]] ];
}
// If we have a "--dpi" along with a corresponding argument ...
unsigned int index = NSNotFound;
if ( (index = [args indexOfObject: @"--dpi"]) != NSNotFound && index + 1 < [args count] )
{
// Parse it as an integer
destinationSize = [[args objectAtIndex: index + 1] intValue];
[args removeObjectAtIndex: index + 1];
[args removeObjectAtIndex: index];
}
if ( [args count] != 2 || [args indexOfObject: @"--help"] != NSNotFound || destinationSize <= 0 )
{
fprintf( stderr, "resizePicture [options] file\n" );
fprintf( stderr, "\t--dpi dpi\tSpecifies the destination size of the image in pixels\n" );
fprintf( stderr, "\t--help\tPrint this help message\n" );
return 1;
}
NSString* sourcePath = [args objectAtIndex: 0];
NSImage* source = [ [NSImage alloc] initWithContentsOfFile: sourcePath ];
[source setScalesWhenResized: YES];
// Tip from http://www.omnigroup.com/mailman/archive/macosx-dev/2002-February/023366.html
// Allows setCurrentPage to do anything
[source setDataRetained: YES];
if ( source == nil )
{
fprintf( stderr, "Source image '%s' could not be loaded\n", argv[1] );
return 2;
}
// The output file name
NSString* outputFilePath = [args objectAtIndex: 1];
NSSize sourceSize = [source size];
NSSize size = NSMakeSize( destinationSize, destinationSize );
[NSApplication sharedApplication];
[[NSGraphicsContext currentContext] setImageInterpolation: NSImageInterpolationHigh];
[source setSize: size];
NSRect destinationRect = NSMakeRect( 0, 0, size.width, size.height );
NSImage* image = [[NSImage alloc] initWithSize:size];
[image lockFocus];
NSEraseRect( destinationRect );
[source drawInRect: destinationRect
fromRect: destinationRect
operation: NSCompositeCopy fraction: 1.0];
NSBitmapImageRep* bitmap = [ [NSBitmapImageRep alloc]
initWithFocusedViewRect: destinationRect ];
NSData* data = [bitmap representationUsingType:NSPNGFileType properties:nil];
[bitmap release];
[[NSFileManager defaultManager]
createFileAtPath: outputFilePath
contents: data
attributes: nil ];
[image unlockFocus];
[image release];
[pool release];
}
|
|
|
 |
|
Updated $LastChangedDate: 2005-01-07 20:53:38 +0100 (Fri, 07 Jan 2005) $ |
 |
Kristof Van Landschoot
Author
|
 |
|
Summary:
We need to get the images out of the mp3 files, they're in there
somewhere. This section explains how to get them out.
|
 |
Single-page Version |
|