ページ

2008年8月4日月曜日

SimpleCap (33) アプリケーションキャプチャ(4)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

PIDがわたってくれば後は簡単。Windowsキャプチャなどと同じ方法でキャプチャできる。違いは条件にPIDが加わるだけ。
CGImageRef を作成するコードは次のようになる。

ApplicationHandler.m

- (CGImageRef)capture
{
CFDictionaryRef window;
CGRect cgrect = CGRectNull;
CGImageRef cgimage = nil;
int window_id;
CFIndex i;
NSMutableArray *application_windows = [NSMutableArray array];
int pid = [[_application objectForKey:@"pid"] intValue];
int owner_pid;

CFArrayRef window_list = [self getWindowListWindowID:kCGNullWindowID];
for (i=0; i < CFArrayGetCount(window_list); i++) {
window = CFArrayGetValueAtIndex(window_list, i);

CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowOwnerPID),
kCFNumberIntType, &owner_pid);
CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowNumber),
kCGWindowIDCFNumberType, &window_id);
if (pid == owner_pid) {
[application_windows addObject:[NSNumber numberWithInt:window_id]];
}
}

if ([application_windows count]) {

CGWindowID *windowIDs = calloc([application_windows count], sizeof(CGWindowID));
int widx;
for (widx=0; widx < [application_windows count]; widx++) {
windowIDs[widx] = [[application_windows objectAtIndex:widx] intValue];
}
CFArrayRef windowIDsArray = CFArrayCreate(kCFAllocatorDefault, (const void**)windowIDs, widx, NULL);
cgimage = CGWindowListCreateImageFromArray(cgrect, windowIDsArray, kCGWindowImageDefault);
free(windowIDs);
CFRelease(windowIDsArray);
}
CFRelease(window_list);
return cgimage;
}


ターゲットのアプリケーションの PIDと OwnerPIDが一致するウィンドウを一旦 application_windows へ入れておき、最後にこれを CGWindowListCreateImageFromArray へ渡してキャプチャ画像を得る。

実行してみる。Finderをターゲットとしてみよう。


メニューから Application > Finder を選択する。


タイマーが起動し、しばらく待つとキャプチャ画像ができる。いい感じだ。


IntefaceBuilder の接続線もこの通り。


- - - -
元々 Application キャプチャを作ろうと思い立ったのは InterfaceBuilderの接続線を撮りたかったから。ついにこれもキャプチャできるようになりうれしい。