NSImage to JUCE Image?

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.

2 Likes

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 {};
}