I need to take the contents of an NSView and put them in an NSImage, for an experimental project. Is this possible? I did some Googling, tried two methods that I found - but they didn't really work. Any suggestions?
Asked
Active
Viewed 9,673 times
14
Justin Boo
- 10,034
- 8
- 49
- 71
Debashis
- 159
- 1
- 4
-
4Which methods didn't work and why? – Georg Fritzsche Jul 14 '10 at 23:20
4 Answers
26
From WWDC 2012 Session 245 (translated to Swift):
let viewToCapture = self.window!.contentView!
let rep = viewToCapture.bitmapImageRepForCachingDisplay(in: viewToCapture.bounds)!
viewToCapture.cacheDisplay(in: viewToCapture.bounds, to: rep)
let img = NSImage(size: viewToCapture.bounds.size)
img.addRepresentation(rep)
-
swift 3 let rep = viewToCapture.bitmapImageRepForCachingDisplay(in: viewToCapture.bounds)! viewToCapture.cacheDisplay(in: viewToCapture.bounds, to: rep) let img = NSImage(size: viewToCapture.bounds.size) img.addRepresentation(rep) – spacecash21 Jul 02 '17 at 17:56
-
Note: doesn't always work correctly. I'm having issued with a label that has a rotated coordinate system. – Ash Jul 04 '17 at 14:16
-
2This was the best solution for me, unlike the pdf version, this also accounts for shadows and rounded corners. Unlike the window cap version, this only captures the current view. Obj C code: `- (NSImage *)screenCap { NSBitmapImageRep *bitmap = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; [self cacheDisplayInRect:self.bounds toBitmapImageRep:bitmap]; NSImage *result = [[NSImage alloc] initWithSize:self.bounds.size]; [result addRepresentation:bitmap]; return result; } ` – codrut Oct 16 '17 at 13:36
-
I've been using this successfully in 10.14 & 10.15 (codrut's Obj C version above) but for some reason I get no image on 10.13. – w0mbat Aug 14 '20 at 17:49
23
[[NSImage alloc] initWithData:[view dataWithPDFInsideRect:[view bounds]]];
Chuck
- 228,856
- 29
- 291
- 386
-
2+1 It's worth noting that, although this is the right way in general, there are some cases where it will not work, eg views like `NSOpenGLView` that have their own OpenGL rendering context. In that case you need to get the pixel data directly and create a bitmap rep from it, which is a bit less neat. – walkytalky Jul 19 '10 at 01:11
-
-
If view is layer backed (wantsLayer = YES) this solution will ignore some layer properties, like backgroundColor, cornerRadius etc. I recommend code from another answer, using cacheDisplayInRect function, it should work in all cases. – Slyv Sep 25 '18 at 13:23
6
let dataOfView = view.dataWithPDFInsideRect(view.bounds)
let imageOfView = NSImage(data: dataOfView)
Zelko
- 3,529
- 3
- 31
- 37
3
I thinkt, Debashis is thinking more of things like http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Images/Images.html#//apple_ref/doc/uid/TP40003290-CH208-BCIIIJFB
Greetings
-
2
-
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html – j.unruh Jan 25 '20 at 10:19