2013-02-02 11 views
2

나는 Son of Grab Apple 데모를 공부 해왔고 어떤 창도없는 스크린 샷 (데스크탑, 독 및 메뉴 바 만)을 얻으려고 정말 고심하고 있습니다. 아무도 그렇게하는 방법을 알고 있습니까?Window없이 스크린 샷 찍기

답변

3

다음은 데스크톱만으로 스크린 샷을 찍는 예제 코드입니다.

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) 이상의 항목을 원할 것입니다.

+0

대단히 감사합니다! 장갑처럼 잘 어울립니다! –

+1

당신을 진심으로 환영합니다. 내 샘플 코드에는 적절한 메모리 관리가 포함되지 않았다는 것을 언급해야한다. 배열과 CGImage가 끝나면'CFRelease()'를 잊지 마라. ARC를 사용하지 않는다면 NSBitmapImageRep도 해제해야합니다. –

+0

나는 모든 것을 거기서 만들어내는 것을 잊지 않을 것입니다. D 좋은 조언이었습니다! –