코어 그래픽 프레임 워크의 기능인 Quartz Window Services을 통해 macOS에서 화면 캡처가 가능합니다. 우리의 주요 기능은 CGWindowListCreateImage
입니다. "동적으로 생성 된 창 목록을 기반으로 합성 이미지를 반환합니다."즉, 지정된 기준에 따라 창을 찾고 각각의 내용으로 이미지를 만듭니다. 완전한!
CGImageRef CGWindowListCreateImage(CGRect screenBounds,
CGWindowListOption listOption,
CGWindowID windowID,
CGWindowImageOption imageOption);
그래서, 화면에 하나 개의 특정 창을 캡처하기 위해, 우리는 윈도우 ID (CGWindowID
)를해야합니다 다음과 같이 선언이다. 검색을 위해 먼저 시스템에서 사용할 수있는 모든 창 목록이 필요합니다. CGWindowListCopyWindowInfo
을 통해이를 얻으므로 CGWindowListOption
초이고 해당하는 CGWindowID
이 함께 결과 목록에 포함 할 창을 선택합니다. 모든 창을 얻으려면 kCGWindowListOptionAll
및 kCGNullWindowID
을 각각 지정하십시오. 또한 이미 알아 내지 못했다면 C API이므로 브리징 캐스트를 사용하여 Core Foundation보다 더 친숙한 Objective-C 컨테이너로 작업 할 것입니다.
목표 - C :
NSArray<NSDictionary*> *windowInfoList = (__bridge_transfer id)
CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
스위프트 : 여기에서
let windowInfoList = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID)!
as NSArray
, 우리는 필터링해야 우리 windowInfoList
우리가 원하는 특정 창 아래로. 먼저 응용 프로그램별로 필터링 할 가능성이 있습니다. 그렇게하기 위해서는 우리가 선택한 응용 프로그램의 프로세스 ID가 필요합니다.
목표 - C :
NSArray<NSRunningApplication*> *apps =
[NSRunningApplication runningApplicationsWithBundleIdentifier:
/* Bundle ID of the application, e.g.: */ @"com.apple.Safari"];
if (apps.count == 0) {
// Application is not currently running
puts("The application is not running");
return; // Or whatever
}
pid_t appPID = apps[0].processIdentifier;
스위프트 : 우리는이 달성하기 위해 NSRunningApplication
을 사용할 수 있습니다 손에 appPID
으로
let apps = NSRunningApplication.runningApplications(withBundleIdentifier:
/* Bundle ID of the application, e.g.: */ "com.apple.Safari")
if apps.isEmpty {
// Application is not currently running
print("The application is not running")
return // Or whatever
}
let appPID = apps[0].processIdentifier
을, 우리는 지금 가서 아래로 필터링 할 수 있습니다 우리의 일치하는 소유자가있는 창에만 창 정보 목록 표시 :
목표 - C :
NSMutableArray<NSDictionary*> *appWindowsInfoList = [NSMutableArray new];
for (NSDictionary *info in windowInfoList) {
if ([info[(__bridge NSString *)kCGWindowOwnerPID] integerValue] == appPID) {
[appWindowsInfoList addObject:info];
}
}
스위프트 : 우리는 정보의 다른 키를 테스트하여 위의 추가 필터링을 할 수 있었다
var appWindowsInfoList = [NSDictionary]()
for info_ in windowInfoList {
let info = info_ as! NSDictionary
if (info[kCGWindowOwnerPID as NSString] as! NSNumber).intValue == appPID {
appWindowsInfoList.append(info)
}
}
사전 - 예를 들어, 이름 (kCGWindowName
)에 의해, 또는 창이 화면에 표시되는지 (kCGWindowIsOnscreen
) - 현재로서는 목록의 첫 번째 창을 가져옵니다.
목표 - C :
NSDictionary *appWindowInfo = appWindowsInfoList[0];
CGWindowID windowID = [appWindowInfo[(__bridge NSString *)kCGWindowNumber] unsignedIntValue];
스위프트 :
let appWindowInfo: NSDictionary = appWindowsInfoList[0];
let windowID: CGWindowID = (appWindowInfo[kCGWindowNumber as NSString] as! NSNumber).uint32Value
그리고 우리는 우리의 창 ID를 가지고! 이제 그 전화에 또 뭐가 필요 했나요?
CGImageRef CGWindowListCreateImage(CGRect screenBounds,
CGWindowListOption listOption,
CGWindowID windowID,
CGWindowImageOption imageOption);
먼저
, 우리는 캡처하는
screenBounds
이 필요합니다.
the documentation에 따르면이 매개 변수에 대해
CGRectNull
을 지정하여 지정된 모든 창을 최대한 단 ~ 으로 지정할 수 있습니다. 나를 위해 일합니다.
두 번째로, 우리는 listOption
으로 창을 선택하는 방법을 지정해야합니다. 실제로 우리는 CGWindowListCopyWindowInfo
을 호출 할 때 이전에이 중 하나를 사용했지만 시스템의 모든 창을 원했습니다. 여기, 우리는 하나를 원하는, 그래서 우리는, 은 우리가 전달하는 윈도우를 지정한다는 점에서 CGWindowListCreateImage
에 대한 자체에 의미입니다 its documentation page는 달리, kCGWindowListOptionIncludingWindow
, 및 만 우리가 통과 창을 지정할 수 있습니다.
세 번째로 캡처 할 창으로 windowID
을 전달합니다.
마지막으로 imageOption
매개 변수를 사용하여 CGWindowImageOption
을 지정할 수 있습니다. 이는 결과 이미지의 모양에 영향을줍니다. 비트 OR로 결합 할 수 있습니다.전체 목록은 here이지만 일반적인 내용은 프레임과 그림자와 함께 창 내용을 캡처하는 kCGWindowImageDefault
또는 내용 만 캡처하는 kCGWindowImageBoundsIgnoreFraming
과 가능한 한 최상의 해상도로 창 콘텐츠를 캡처하는 kCGWindowImageBestResolution
중 하나를 포함합니다. 실제 크기 (및 창에 따라 상당히 클 수 있음) 또는 kCGWindowImageNominalResolution
. 화면의 현재 크기로 창을 캡처합니다. 여기서는 kCGWindowImageBoundsIgnoreFraming
과 kCGWindowImageNominalResolution
을 사용하여 화면과 동일한 크기로만 콘텐츠를 캡처합니다.
Aaand, 제발 드럼 롤 :
목표 - C :
CGImageRef windowImage =
CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow,
windowID, kCGWindowImageBoundsIgnoreFraming|
kCGWindowImageNominalResolution);
// NOTE: windowImage may be NULL if the capture failed
스위프트 : I 오프 주제로이 질문을 닫으 투표 해요
let windowImage: CGImage? =
CGWindowListCreateImage(.null, .optionIncludingWindow, windowID,
[.boundsIgnoreFraming, .nominalResolution])
당신 때문에 실제로 당신이 직접 대답 해줄 때 질문을하는 척하십시오. –
@ElTomato https://stackoverflow.com/help/self-answer – ThatsJustCheesy
내 사과 ... –