Cocoa:截取桌面壁纸(没有图标和窗口)

时间:2011-11-10 16:27:38

标签: cocoa screenshot sandbox

是否可以在没有桌面项目和任何可能打开的窗口(即只是壁纸)的情况下捕获Mac OS X桌面?

我已尝试过CGWindowListCreateImageCGWindowListCreateImageFromArrayCGDisplayCreateImage,但没有运气。

基本上我试图在不使用[NSWorkspace desktopImageURLForScreen:]的情况下捕获桌面墙纸(它是一个无法访问文件系统的沙盒应用程序)。

3 个答案:

答案 0 :(得分:5)

您需要小心测试这仍然是正确的,但桌面窗口位于Finder下方(由Dock绘制)。将kCGWindowListOptionOnScreenBelowWindow CGWindowListOption传递给CGWindowListCreateImage可以获得您想要的内容(除非其他内容低于该级别)。

否则,您需要使用CGWindowListCreate并遍历响应,不包括窗口级别kCGMinimumWindowLevel + 19上未由停靠点绘制的任何内容。

当有多个屏幕时,它会变得有点棘手,但希望这些信息足以让您做到所需的一切。

答案 1 :(得分:4)

我知道这是一个非常古老的问题,Tony Arnold的问题是正确的,我用来构建自己的“抢桌面”代码。

我有一些示例代码,展示了如何完成所有这些事情(在Cocoa的部分内容中,这是一个奇妙的事情,几乎没有记录......)

我已将该示例代码放在bitbucket存储库中。具体来说是the code sample to take a picture。 (我的learning Cocoa存储库中有更多有趣的Cocoa代码,其示例代码来自)

答案 2 :(得分:1)

Swift版本:

extension NSImage {

    static func desktopPicture() -> NSImage {

        let windows = CGWindowListCopyWindowInfo(
            CGWindowListOption.OptionOnScreenOnly,
            CGWindowID(0))! as NSArray

        var index = 0
        for var i = 0; i < windows.count; i++  {
            let window = windows[i]

            // we need windows owned by Dock
            let owner = window["kCGWindowOwnerName"] as! String
            if owner != "Dock" {
                continue
            }

            // we need windows named like "Desktop Picture %"
            let name = window["kCGWindowName"] as! String
            if !name.hasPrefix("Desktop Picture") {
                continue
            }

            // wee need the one which belongs to the current screen
            let bounds = window["kCGWindowBounds"] as! NSDictionary
            let x = bounds["X"] as! CGFloat
            if x == NSScreen.mainScreen()!.frame.origin.x {
                index = window["kCGWindowNumber"] as! Int
                break
            }
        }

        let cgImage = CGWindowListCreateImage(
            CGRectZero,
            CGWindowListOption(arrayLiteral: CGWindowListOption.OptionIncludingWindow),
            CGWindowID(index),
            CGWindowImageOption.Default)!

        let image = NSImage(CGImage: cgImage, size: NSScreen.mainScreen()!.frame.size)
        return image
    }
}