ページ

2008年3月14日金曜日

画面キャプチャその13 - 複数のウィンドウをキャプチャ(2)

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

前回の続き。


選択したウィンドウを覚えておくために Winodwクラスを新規に作成する。

@interface Window : NSObject {

CGWindowID _window_id;
NSRect _rect;
CFIndex _order;
}


ウィンドウの選択毎に Windowのインスタンスを作成して CGWindowIDや矩形領域、表示順序をとっておく。

キー入力があったらとっておいた Windowの情報を元に最終画像を合成する。まず全てのウィンドウを含む矩形領域のサイズを算出する。これは NSUnionRect()関数を使うと簡単にできる。
 for (Window* w in list) {
wrect = [w rect];
irect = NSUnionRect(irect, wrect);
}
NSImage* bigimg = [[NSImage alloc] initWithSize:irect.size];



最終画像をおさめる NSImageが用意できたらキャプチャ画像を1つ1つ取得し compositeToPoint: で合成していく。
 for (Window* w in list) {
wrect = [w rect];
rect = CGRectMake(wrect.origin.x, wrect.origin.y, wrect.size.width, wrect.size.height);
cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow, [w windowID], kCGWindowImageDefault);
bitmap_rep = [[[NSBitmapImageRep alloc] initWithCGImage:cgimage] autorelease];
image = [[[NSImage alloc] init] autorelease];
[image addRepresentation:bitmap_rep];
p.x = wrect.origin.x - irect.origin.x;
p.y = (irect.size.height - wrect.size.height) - (wrect.origin.y - irect.origin.y);
[bigimg lockFocus];
[image compositeToPoint:p operation:NSCompositeSourceOver];
[bigimg unlockFocus];
}


この時 NSImageの座標系は左下が原点、CGWindowListCreateImage()が左上が原点、とことなるので補正しておく。

合成が終わったら後はファイルへ書き出してやる。
 NSData* data = [bigimg TIFFRepresentation];
NSBitmapImageRep *pngrep = [NSBitmapImageRep imageRepWithData:data];
data = [pngrep representationUsingType:NSPNGFileType
properties:[NSDictionary dictionary]];
[data writeToFile:filename atomically:YES];


- - - -
今のままだとウィンドウの陰が含まれていないので、のっぺりした感じになってしまうな。