What is the easiest way to get a juce::Image from an NSImage, on OSX?
I don’t think there’s anything in the codebase for doing exactly that, but there is a juce_createImageFromUIImage()
method in juce_mac_CoreGraphicsContext.mm
here that we use on iOS. That should be a good starting point for doing the same with an NSImage
.
I tried to use the code of the juce_createImageFromUIImage() method, but I got lost in dependencies errors. Here is a method which worked.
Here is a code to get a CGImage from a NSImage:
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)[img TIFFRepresentation], NULL);
CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
Here is how to get the pixels data from a CGImage: https://developer.apple.com/library/content/qa/qa1509/_index.html
Here is how to fill up your juce::Image with the data:
if (data != NULL)
{
unsigned char r, g, b;
Image juceImage (Image::ARGB, (int) img.size.width, (int) img.size.height, true);
for(int y = 0; y < juceImage.getHeight(); y++) {
for(int x = 0; x < juceImage.getWidth(); x++) {
r = *(data+1);
g = *(data+2);
b = *(data+3);
Colour lColor(r,g,b);
juceImage.setPixelAt(x, y, lColor);
data = data + 4;
}
}
return juceImage;
}
So I can read my pdf, and I can draw on top of it. yay.
That’s going to be really inefficient - you should look at the Image::BitmapData class if you’re doing more than setting a couple of pixels
Thank you, much faster. I think I would have ended up using that. It was quite slow indeed.
Might not be the most efficient, but here is an easy way to do it.
Image createJuceImage (NSImage* nsImage)
{
if (nsImage != nil)
{
[nsImage lockFocus];
NSBitmapImageRep* bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect (0, 0, nsImage.size.width, nsImage.size.height)];
[nsImage unlockFocus];
NSDictionary* dic = [NSDictionary dictionary];
NSData* data = [bitmapRep representationUsingType:NSPNGFileType properties:dic];
return PNGImageFormat::loadFrom (data.bytes, data.length);
}
return {};
}