开发者

How do I take a "screenshot" of an NSView?

开发者 https://www.devze.com 2023-01-07 00:28 出处:网络
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\'

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号