NSWindow视图捕获到图像

时间:2018-11-05 00:59:10

标签: macos swift3

更新:11月6日

感谢pointum,我修改了我的问题。

在10.13上,我试图将视图快照功能编写为通用NSView或窗口扩展。这是我作为窗口代表的观点:

var snapshot : NSImage? {
    get {
        guard let window = self.window, let view = self.window!.contentView else { return nil }

        var rect = view.bounds
        rect = view.convert(rect, to: nil)
        rect = window.convertToScreen(rect)

        //  Adjust for titlebar; kTitleUtility = 16, kTitleNormal = 22
        let delta : CGFloat = CGFloat((window.styleMask.contains(.utilityWindow) ? kTitleUtility : kTitleNormal))
        rect.origin.y += delta
        rect.size.height += delta*2

        Swift.print("rect: \(rect)")

        let cgImage = CGWindowListCreateImage(rect, .optionIncludingWindow,
                                              CGWindowID(window.windowNumber), .bestResolution)
        let image = NSImage(cgImage: cgImage!, size: rect.size)

        return image
    }
}
我想要的是

以获得窗口的“展平”快照。最初,我在文档图标拖动中使用此图像。

行为异常。它似乎一开始就可以工作-窗口居中,但是随后生成的图像却有所不同-较小,尤其是当窗口在屏幕中上下移动时。

我认为直肠捕获是错误的吗?

2 个答案:

答案 0 :(得分:2)

使用CGWindowListCreateImage

let rect = /* view bounds converted to screen coordinates */
let image = CGWindowListCreateImage(rect, .optionIncludingWindow,
    CGWindowID(window.windowNumber), .bestResolution)

要保存图像,请使用以下内容:

let dest = CGImageDestinationCreateWithURL(url, "public.jpeg", 1, nil)
CGImageDestinationAddImage(destination, image, nil)
CGImageDestinationFinalize(destination)

请注意,屏幕坐标已翻转。从文档中:

  

必须在屏幕坐标中指定矩形的坐标,其中屏幕原点位于主显示屏的左上角,并且y轴值向下增大

答案 1 :(得分:1)

除了要点的答案外,我想到了这一点:

var snapshot : NSImage? {
    get {
        guard let window = self.window, let view = self.window!.contentView else { return nil }

        let inf = CGFloat(FP_INFINITE)
        let null = CGRect(x: inf, y: inf, width: 0, height: 0)

        let cgImage = CGWindowListCreateImage(null, .optionIncludingWindow,
                                              CGWindowID(window.windowNumber), .bestResolution)
        let image = NSImage(cgImage: cgImage!, size: view.bounds.size)

        return image
    }
}

因为我只希望/需要一个窗口,所以指定“ null”就可以了。好吧,文档,如果您知道在哪里看,其他所有方法都会失败。