我一直在研究Son Of Grab Apple演示,我真的很难获得没有任何窗口的屏幕截图(只有桌面,底座和菜单栏)。有谁知道怎么做?
答案 0 :(得分:4)
以下是一些示例代码,它仅使用桌面进行屏幕截图。
CFArrayRef onScreenWindows = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
CFArrayRef nonDesktopElements = CGWindowListCreate(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
CFRange range = CFRangeMake(0, CFArrayGetCount(nonDesktopElements));
CFMutableArrayRef desktopElements = CFArrayCreateMutableCopy(NULL, 0, onScreenWindows);
for (int i = CFArrayGetCount(desktopElements) - 1; i >= 0; i--)
{
CGWindowID window = (CGWindowID)(uintptr_t)CFArrayGetValueAtIndex(desktopElements, i);
if (CFArrayContainsValue(nonDesktopElements, range, (void*)(uintptr_t)window))
CFArrayRemoveValueAtIndex(desktopElements, i);
}
CGImageRef cgimage = CGWindowListCreateImageFromArray(CGRectInfinite, desktopElements, kCGWindowListOptionAll);
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCGImage:cgimage];
NSData* data = [rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]];
[data writeToFile:@"/tmp/foo.png" atomically:YES];
您应该能够扩展抓住Dock和菜单栏的一般方法。您构建了一个您感兴趣的窗口ID列表,然后调用CGWindowListCreateImageFromArray()
。我通过询问所有屏幕上的窗口以及除桌面元素之外的所有屏幕窗口来计算桌面元素的窗口ID。桌面元素是第一个列表中不在第二个列表中的元素。
获取菜单栏和Dock的窗口ID并不像那样直接,因为CGWindowList API中没有与此直接对应的选项。您需要使用CGWindowListCopyWindowInfo()
或CGWindowListCreateDescriptionFromArray()
获取屏幕窗口的描述字典数组并检查内容。最有用的密钥可能是kCGWindowLayer
。除了在我的示例代码中使用该技术获得的桌面元素之外,我认为您需要CGWindowLevelForKey(kCGDockWindowLevelKey)
以及更高的任何内容。