Draw standard NSImage inverted (white instead of black)

drawing, macos, nsimage, objective-c

Solution

The Core Image route would be the most reliable. It's actually not very complicated, I've posted a sample below. If you know none of your images will be flipped then you can remove the transform code. The main thing to be careful of is that the conversion from `NSImage` to `CIImage` can be expensive performance-wise, so you should ensure you cache the `CIImage` if possible and don't re-create it during each drawing operation.

CIImage* ciImage = [[CIImage alloc] initWithData:[yourImage TIFFRepresentation]];
if ([yourImage isFlipped])
{
    CGRect cgRect    = [ciImage extent];
    CGAffineTransform transform;
    transform = CGAffineTransformMakeTranslation(0.0,cgRect.size.height);
    transform = CGAffineTransformScale(transform, 1.0, -1.0);
    ciImage   = [ciImage imageByApplyingTransform:transform];
}
CIFilter* filter = [CIFilter filterWithName:@"CIColorInvert"];
[filter setDefaults];
[filter setValue:ciImage forKey:@"inputImage"];
CIImage* output = [filter valueForKey:@"outputImage"];
[output drawAtPoint:NSZeroPoint fromRect:NSRectFromCGRect([output extent]) operation:NSCompositeSourceOver fraction:1.0];

Note: release/retain memory management is left as an exercise, the code above assumes garbage collection.

If you want to render the image at an arbitrary size, you could do the following:

NSSize imageSize = NSMakeSize(1024,768); //or whatever size you want
[yourImage setSize:imageSize];
[yourImage lockFocus];
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, imageSize.width, imageSize.height)];
[yourImage unlockFocus];
CIImage* image = [CIImage imageWithData:[bitmap TIFFRepresentation]];

Problem

I'm trying to draw a standard NSImage in white instead of black. The following works fine for drawing the image in black in the current NSGraphicsContext: ``` NSImage* image = [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; [image drawInRect:r fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; ``` I expected NSCompositeXOR to do the trick, but no. Do I need to go down the complicated [CIFilter filterWithName:@"CIColorInvert"] path? I feel like I must be missing something simple.

Original source