Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display NSImage on a CALayer

I've been trying to display a NSImage on a CALayer. Then I realised I need to convert it to a CGImage apparently, then display it...

I have this code which doesn't seem to be working

CALayer *layer = [CALayer layer];

    NSImage *finderIcon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kFinderIcon)];
    [finderIcon setSize:(NSSize){ 128.0f, 128.0f }];

    CGImageSourceRef source;
    source = CGImageSourceCreateWithData((CFDataRef)finderIcon, NULL);
    CGImageRef finalIcon =  CGImageSourceCreateImageAtIndex(source, 0, NULL);

    layer.bounds = CGRectMake(128.0f, 128.0f, 4, 4);
    layer.position = CGPointMake(128.0f, 128.0f);
    layer.contents = finalIcon;

        // Insert the layer into the root layer
    [mainLayer addSublayer:layer];

Why? How can I get this to work?

like image 355
Seb Jachec Avatar asked Jan 27 '26 20:01

Seb Jachec


1 Answers

From the comments: Actually, if you're on 10.6, you can also just set the CALayer's contents to an NSImage rather than a CGImageRef...


If you're on OS X 10.6 or later, take a look at NSImage's CGImageForProposedRect:context:hints: method.

If you're not, I've got this in a category on NSImage:

-(CGImageRef)CGImage
{
    CGContextRef bitmapCtx = CGBitmapContextCreate(NULL/*data - pass NULL to let CG allocate the memory*/, 
                                                   [self size].width,  
                                                   [self size].height, 
                                                   8 /*bitsPerComponent*/, 
                                                   0 /*bytesPerRow - CG will calculate it for you if it's allocating the data.  This might get padded out a bit for better alignment*/, 
                                                   [[NSColorSpace genericRGBColorSpace] CGColorSpace], 
                                                   kCGBitmapByteOrder32Host|kCGImageAlphaPremultipliedFirst);

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

    CGImageRef cgImage = CGBitmapContextCreateImage(bitmapCtx);
    CGContextRelease(bitmapCtx);

    return (CGImageRef)[(id)cgImage autorelease];
}

I think I wrote this myself. But it's entirely possible that I ripped it off from somewhere else like Stack Overflow. It's an older personal project and I don't really remember.

like image 191
James Williams Avatar answered Jan 29 '26 10:01

James Williams