Using Cocoa to Convert Images From RGB to CMYK

Today in the office, someone needed to convert a bunch of images from RGB to CMYK. Not many programs beside Photoshop can deal with CMYK. ImageMagick can also do it and is easy to use in a scripted environment, but I would have to spend hours in the man pages to make ImageMagick do what I want.

So why not do it in Cocoa? Turns out it only takes a few lines. This is the basic algorithm:

NSImage *sourceImage = [[[NSImage alloc] initWithContentsOfFile:sourceFilename] autorelease];
NSBitmapImageRep *sourceImageRep = [[sourceImage representations] objectAtIndex:0];

NSColorSpace *targetColorSpace = [NSColorSpace genericCMYKColorSpace];
NSBitmapImageRep *targetImageRep = [sourceImageRep bitmapImageRepByConvertingToColorSpace:targetColorSpace
    renderingIntent:NSColorRenderingIntentPerceptual];
return targetImageRep;

We simply load an NSImage, ask it for its bitmap representation and then send it a bitmapImageRepByConvertingToColorSpace:renderingIntent: message with the CMYK color space as the first argument. You can play with different values for the renderingIntent argument to specify how to handle color that are not present in the target color space. See the documentation for possible values.

You can get the code for the full command line app from GitHub. To use it, simply pass the names of the files you want to convert on the command line.

One nice touch: I use Apple’s block-based enumeration method to loop through the command line arguments. This lets me process the images concurrently so the app should scale quite well without any effort on my part. Simply pass NSEnumerationConcurrent to the enumeration method to enable concurrent execution:

[commandLineArguments enumerateObjectsWithOptions:NSEnumerationConcurrent
    usingBlock:^(id filename, NSUInteger idx, BOOL *stop) {
    ...
}];