Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering NSView containing some CALayers to an NSImage

I have an NSView that contains an NSScrollView containing a CALayer-backed NSView. I've tried all the usual methods of capturing an NSView into an NSImage (using -dataWithPDFInsideRect, NSBitmapImageRep's -initWithFocusedViewRect, etc.) However, all these methods treat the CALayer-backed NSView as if it doesn't exist. I've already seen this StackOverflow post, but it was a question about rendering just a CALayer tree to an image, not an NSView containing both regular NSView's and layer-backed views.

Any help is appreciated, thanks :)

like image 456
indragie Avatar asked Dec 23 '10 05:12

indragie


2 Answers

The only way I found to do this is to use the CGWindow API's, something like:

CGImageRef cgimg = CGWindowListCreateImage(CGRectZero, kCGWindowListOptionIncludingWindow, [theWindow windowNumber], kCGWindowImageDefault);

then clip out the part of that CGImage that corresponds to your view with

-imageByCroppingToRect.

Then make a NSImage from the cropped CGImage. Be aware this won't work well if parts of that window are offscreen.

like image 102
Rainer Brockerhoff Avatar answered Nov 17 '22 17:11

Rainer Brockerhoff


This works to draw a view directly to an NSImage, though I haven't tried it with a layer-backed view:

NSImage * i = [[NSImage alloc] initWithSize:[view frame].size];
[i lockFocus];
if ([view lockFocusIfCanDrawInContext:[NSGraphicsContext currentContext]]) {
  [view displayRectIgnoringOpacity:[view frame] inContext:[NSGraphicsContext currentContext]];
  [view unlockFocus];
}
[i unlockFocus];

NSData * d = [i TIFFRepresentation];
[d writeToFile:@"/path/to/my/test.tiff" atomically:YES];
[i release];
like image 27
Dave DeLong Avatar answered Nov 17 '22 18:11

Dave DeLong