4

I need to get a CGIImageRef from an NSImage. Is there an easy way to do this in Cocoa for Mac OS X?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike2012
  • 7,629
  • 15
  • 84
  • 135

2 Answers2

15

Pretty hard to miss:

-[NSImage CGImageForProposedRect:context:hints:]

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
Azeem.Butt
  • 5,855
  • 1
  • 26
  • 22
5

If you need to target Mac OS X 10.5 or any other previous release, use the following snippet instead. If you don’t, then NSD’s answer is the right way to go.

CGImageRef CGImageCreateWithNSImage(NSImage *image) {
    NSSize imageSize = [image size];

    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, 0, [[NSColorSpace genericRGBColorSpace] CGColorSpace], kCGBitmapByteOrder32Host|kCGImageAlphaPremultipliedFirst);

    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:bitmapContext flipped:NO]];
    [image drawInRect:NSMakeRect(0, 0, imageSize.width, imageSize.height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
    [NSGraphicsContext restoreGraphicsState];

    CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
    CGContextRelease(bitmapContext);
    return cgImage;
}

If your image comes from a file you may be better off using an image source to load the data directly into a CGImageRef.

Ben Stiglitz
  • 3,994
  • 27
  • 24
  • I did something similar to this to use the data from the bitmapContext. An important gotcha: if you want to use the data from the context, you need to call flushGraphics on the NSGraphicsContext. Without this it worked fine in debug mode but segfaulted in release mode. – Sam Sep 12 '13 at 11:49