2

私はSonOfGrab Appleのデモを研究してきましたが、ウィンドウなし(デスクトップ、ドック、メニューバーのみ)の画面のスクリーンショットを取得するのに本当に苦労しています。誰かがそうする方法を知っていますか?

4

1 に答える 1

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を計算するには、すべての画面上のウィンドウを要求してから、デスクトップ要素を除くすべての画面上のウィンドウを要求します。デスクトップ要素は、2番目のリストにない最初のリストの要素です。

メニューバーとDockのウィンドウIDを取得することは、それに直接対応するCGWindowList APIのオプションがないため、それほど直接的ではありません。CGWindowListCopyWindowInfo()またはを使用して画面上のウィンドウの説明辞書の配列を取得しCGWindowListCreateDescriptionFromArray()、内容を調べる必要があります。最も有用なキーはおそらくですkCGWindowLayer。私のサンプルコードの手法を使用して取得したデスクトップ要素に加えて、それ以上のものが必要になると思いますCGWindowLevelForKey(kCGDockWindowLevelKey)

于 2013-02-02T22:22:39.130 に答える