NSImage has a slightly different interface to UIImage but uses the same image engine.
Below is how to greyscale an image using NSImage, credit to Stackoverflow for the UIImage version:
- (NSImage *)imageToGreyImage:(NSImage *)image {
// Create image rectangle with current image width/height
CGFloat actualWidth = image.size.width;
CGFloat actualHeight = image.size.height;
CGRect imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, colorSpace, (CGBitmapInfo)kCGImageAlphaNone);
CGContextDrawImage(context, imageRect, [self nsImageToCGImageRef:image]);
CGImageRef grayImage = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, nil, (CGBitmapInfo)kCGImageAlphaOnly);
CGContextDrawImage(context, imageRect, [self nsImageToCGImageRef:image]);
CGImageRef mask = CGBitmapContextCreateImage(context);
CGContextRelease(context);
NSImage *grayScaleImage = [self imageFromCGImageRef:CGImageCreateWithMask(grayImage, mask)];
CGImageRelease(grayImage);
CGImageRelease(mask);
// Return the new grayscale image
return grayScaleImage;
}
- (NSImage*) imageFromCGImageRef:(CGImageRef)image
{
NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
CGContextRef imageContext = nil;
NSImage* newImage = nil; // Get the image dimensions.
imageRect.size.height = CGImageGetHeight(image);
imageRect.size.width = CGImageGetWidth(image);
// Create a new image to receive the Quartz image data.
newImage = [[NSImage alloc] initWithSize:imageRect.size];
[newImage lockFocus];
// Get the Quartz context and draw.
imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image); [newImage unlockFocus];
return newImage;
}
- (CGImageRef)nsImageToCGImageRef:(NSImage*)image;
{
NSData * imageData = [image TIFFRepresentation];
CGImageRef imageRef;
if(!imageData) return nil;
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
return imageRef;
}
Thank you for this.
ReplyDeleteBTW you have a memory leak in nsImageToCGImageRef
CGImageSourceCreateWithData call needs CFRelease