iosobjective-cmacosnsimagensbitmapimagerep

Convert NSImage from CMYK to RGB


After a full day of searching, I've found a few similar answers, but nothing that seems to work for me.

I've built an app to be used in OSX which fetches a list of images from a user inputted directory, runs each through a renaming process, converts to a JPG, and hopefully with your help, converts to RGB color.

NSImage *image = [[NSImage alloc] initWithContentsOfFile:from];

NSInteger imageWidth = image.size.width * 4.16666666667;
NSInteger imageHeight = image.size.height * 4.16666666667;

NSBitmapImageRep* theRGBImageRep = [[NSBitmapImageRep alloc]
    initWithBitmapDataPlanes:NULL pixelsWide:imageWidth pixelsHigh:imageHeight
        bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES isPlanar: NO
    colorSpaceName: NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];

NSGraphicsContext* theContext = [NSGraphicsContext
                    graphicsContextWithBitmapImageRep: theRGBImageRep];

NSImageRep* theImageRep = [image bestRepresentationForRect:
   NSMakeRect(0.0, 0.0, imageWidth, imageHeight) context:theContext
     hints:[NSDictionary dictionaryWithObject:NSDeviceRGBColorSpace
                     forKey:NSDeviceColorSpaceName]];

[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext: theContext];

NSRect theBoundsRect = NSMakeRect(0.0, 0.0, [theRGBImageRep pixelsWide],
                                                [theRGBImageRep pixelsHigh]);

[[NSColor clearColor] set];

NSRectFill(theBoundsRect);

[theImageRep drawInRect: theBoundsRect];
[NSGraphicsContext restoreGraphicsState];;
[image addRepresentation: theRGBImageRep];

NSDictionary *imageProps = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithFloat:1.0],NSImageCompressionFactor, nil];
NSData *bitmapData = [theRGBImageRep representationUsingType:NSJPEGFileType
                   properties:imageProps];

if ([bitmapData writeToFile:toJPG atomically:YES] == YES){
    feedback = [NSString stringWithFormat:@"%@ -> %@\n", string, jpgFileName];
    [readOut insertText:feedback];
    [readOut display];
} else {
    feedback = [NSString stringWithFormat:@"%@ - FAILED\n", string];
    [errorLog insertText:feedback];
    [errorLog display];
}

It the image is output correctly as a JPEG, in the designated folder, but always remains CMYK. Anyone else run into this?

EDITED TO SHOW WASHED OUT RESULTS:

UPDATED CODE (this is what is currently giving washed out results)


Solution

  • try this

    NSImageRep* theImageRep = [inputImage bestRepresentationForDevice:
    [NSDictionary dictionaryWithObject: NSDeviceRGBColorSpace
    
    forKey: NSDeviceColorSpaceName]];
    
    NSString* theColorSpace = [theImageRep colorSpaceName];
    
    if ([theColorSpace isEqualToString: NSDeviceCMYKColorSpace])
    {
    NSBitmapImageRep* theRGBImageRep = [[[NSBitmapImageRep alloc]
    initWithBitmapDataPlanes: NULL
    
    pixelsWide: [theImageRep pixelsWide]
    
    pixelsHigh: [theImageRep pixelsHigh]
    
    bitsPerSample: 8
    
    samplesPerPixel: 4
    
      hasAlpha: YES
    
      isPlanar: NO
    
     colorSpaceName: NSDeviceRGBColorSpace
    
     bytesPerRow: 0
    
     bitsPerPixel: 0] autorelease];
    
    
      NSGraphicsContext* theContext = [NSGraphicsContext
    graphicsContextWithBitmapImageRep: theRGBImageRep];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext: theContext];
    
    NSRect theBoundsRect = NSMakeRect(0.0, 0.0, [theRGBImageRep pixelsWide],
    [theRGBImageRep pixelsHigh]);
    
    [[NSColor clearColor] set];
    NSRectFill(theBoundsRect);
    
    [theImageRep drawInRect: theBoundsRect];
    
    [NSGraphicsContext restoreGraphicsState];
    
    
    ASSIGNOBJECT(rgbImage, [[[NSImage alloc] initWithSize: [theImageRepsize]] autorelease]);
    
    [rgbImage addRepresentation: theRGBImageRep];
    }
    else
    {
    ASSIGNOBJECT(rgbImage, inputImage);
     }