2011-02-09 46 views
1

我一直在试图在CALayer上显示NSImage。然后我意识到我需要它显然转换为CGImage,然后显示它...在CALayer上显示NSImage

我有这样的代码似乎并不奏效

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]; 

为什么?我怎样才能使这个工作?

回答

6

从评论:其实,如果你是在10.6,也可以只设置的CALayer的内容到NSImage中,而不是一个CGImageRef ...


如果你在OS X 10.6或更高版本,请参阅NSImageCGImageForProposedRect:context:hints:方法。

如果你不是,我在一个类别得到这个在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]; 
} 

认为我写了这个自己。但是我完全有可能将它从Stack Overflow等其他位置剥离。这是一个更老的个人项目,我不记得。

+12

其实,如果你是在10.6,也可以只设置了`CALayer`的内容到`NSImage`而不是`CGImageRef` .... – NSGod 2011-02-09 23:54:11

2

下面是一些代码,可以帮助你 - 我当然希望这样的格式不会得到所有搞砸喜欢它似乎将要发生 - 所有我可以提供的是,这对我的作品。

// ------------------------------------------------------------------------------------- 

- (void)awakeFromNib 
    { 
    // setup our main window 'contentWindow' to use layers 
    [[contentWindow contentView] setWantsLayer:YES]; // NSWindow* 

    // create a root layer to contain all of our layers 
    CALayer *root = [[contentWindow contentView] layer]; 
    // use constraint layout to allow sublayers to center themselves 
    root.layoutManager = [CAConstraintLayoutManager layoutManager]; 

    // create a new layer which will contain ALL our sublayers 
    // ------------------------------------------------------- 
    mContainer  = [CALayer layer]; 
    mContainer.bounds = root.bounds; 
    mContainer.frame = root.frame; 
    mContainer.position = CGPointMake(root.bounds.size.width * 0.5, 
         root.bounds.size.height * 0.5); 

    // insert layer on the bottom of the stack so it is behind the controls 
    [root insertSublayer:mContainer atIndex:0]; 

    // make it resize when its superlayer does 
    root.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; 

    // make it resize when its superlayer does 
    mContainer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; 
    } 

// ------------------------------------------------------------------------------------- 

- (void) loadMyImage:(NSString*) path 
      n:(NSInteger) num 
      x:(NSInteger) xpos 
      y:(NSInteger) ypos 
      h:(NSInteger) hgt 
      w:(NSInteger) wid 
      b:(NSString*) blendstr 
    { 
    #ifdef __DEBUG_LOGGING__ 
    NSLog(@"loadMyImage - ENTER [%@] num[%d] x[%d] y[%d] h[%d] w[%d] b[%@]", 
            path, num, xpos, ypos, hgt, wid, blendstr); 
    #endif 

    NSInteger xoffset = ((wid/2) + xpos); // use CORNER versus CENTER for location 
    NSInteger yoffset = ((hgt/2) + ypos); 
    CIFilter* filter = nil; 

    CGRect cgrect = CGRectMake((CGFloat) xoffset, (CGFloat) yoffset, 
            (CGFloat) wid, (CGFloat) hgt); 

    if(nil != blendstr) // would be equivalent to @"CIMultiplyBlendMode" or similar 
     { 
     filter = [CIFilter filterWithName:blendstr];  
     } 

     // read image file via supplied path 
    NSImage* theimage = [[NSImage alloc] initWithContentsOfFile:path]; 

    if(nil != theimage) 
     { 
     [self setMyImageLayer:[CALayer layer]]; // create layer 
     myImageLayer.frame = cgrect;   // locate & size image 
     myImageLayer.compositingFilter = filter; // nil is OK if no filter 
     [myImageLayer setContents:(id) theimage]; // deposit image into layer 
       // add new layer into our main layer [see awakeFromNib above] 
     [mContainer insertSublayer:myImageLayer atIndex:0]; 
     [theimage release]; 
     } 
    else 
     { 
     NSLog(@"ERROR loadMyImage - no such image [%@]", path); 
     } 
    } 
0
+ (CGImageRef) getCachedImage:(NSString *) imageName 
{ 
    NSGraphicsContext *context = [[NSGraphicsContext currentContext] graphicsPort]; 

    NSImage *img = [NSImage imageNamed:imageName]; 

    NSRect rect = NSMakeRect(0, 0, [img size].width, [img size].height); 
    return [img CGImageForProposedRect:&rect context:context hints:NULL]; 
} 


+ (CGImageRef) getImage:(NSString *) imageName withExtension:(NSString *) extension 
{ 
    NSGraphicsContext *context = [[NSGraphicsContext currentContext] graphicsPort]; 

    NSString* imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:extension]; 
    NSImage* img = [[NSImage alloc] initWithContentsOfFile:imagePath]; 

    NSRect rect = NSMakeRect(0, 0, [img size].width, [img size].height); 
    CGImageRef imgRef = [img CGImageForProposedRect:&rect context:context hints:NULL]; 

    [img release]; 

    return imgRef; 
} 

然后可以将其设置:

yourLayer.contents =(ID)[自getCachedImage:@ “myImage.png”];

yourLayer.contents =(ID)[自的getImage:@ “MYIMAGE” withExtension:@ “PNG”];