How do I take a "screenshot" of an NSView?
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?
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)
[[NSImage alloc] initWithData:[view dataWithPDFInsideRect:[view bounds]]];
let dataOfView = view.dataWithPDFInsideRect(view.bounds)
let imageOfView = NSImage(data: dataOfView)
NSView.bitmapImageRepForCachingDisplay()
(mentioned in this answer) doesn't render the colors correctly on some views.
CGWindowListCreateImage()
works perfectly for me.
Here's my implementation:
extension NSView {
@objc func takeScreenshot() -> NSImage? {
let screenRect = self.rectInQuartzScreenCoordinates()
guard let window = self.window else {
assert(false); return nil
}
let windowID = CGWindowID(window.windowNumber)
guard let screenshot = CGWindowListCreateImage(screenRect, .optionIncludingWindow, windowID, []) else {
assert(false); return nil
}
return NSImage(cgImage: screenshot, size: self.frame.size)
}
}
This code uses a method NSView.rectInQuartzScreenCoordinates()
. To implement it you'll first have to convert the bounds of your view to screenCoordinates using NSView
and NSWindow
methods and then you need to flip the coordinates like this.
精彩评论