问题
I've been studying Son Of Grab Apple demo and I'm really struggling to get a screenshot of screen without any window (only desktop, dock and menu bar). Does anyone knows how to do so?
回答1:
Here's some example code which takes a screenshot with just the desktop.
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];
You should be able to extend the general approach to grab the Dock and menu bar. You construct a list of window IDs that you're interested in and then call CGWindowListCreateImageFromArray()
. I compute the window IDs of the desktop elements by asking for all on-screen windows and then all on-screen windows excluding the desktop elements. The desktop elements are those in the first list which aren't in the second list.
Getting the window IDs for the menu bar and Dock is not quite as direct as that because there's no option in the CGWindowList API that directly corresponds to that. You'll need to get the array of description dictionaries for the on-screen windows using either CGWindowListCopyWindowInfo()
or CGWindowListCreateDescriptionFromArray()
and examine the contents. The most useful key will probably be kCGWindowLayer
. In addition to the desktop elements obtained using the technique in my sample code, I think you'll want anything at CGWindowLevelForKey(kCGDockWindowLevelKey)
and greater.
来源:https://stackoverflow.com/questions/14666123/take-screenshot-without-window