ページ

2008年8月19日火曜日

マウスカーソルのキャプチャ (5)

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

スクリーンキャプチャした画像にマウスカーソル画像を合成してみる。

サンプル:MousePointer-3.zip

まずは全画面キャプチャに、NSCursorから取得した矢印カーソルを合成してみる。タイマーを開始すると5秒後に screen.tiff をデスクトップへ作成する。

キャプチャには CGWindowListCreateImage を使い、矢印カーソルは NSCursor#arrowCursor を使う。

- (NSImage*)cursorImage
{
return [[NSCursor arrowCursor] image];
}


- (NSImage*)screenImage
{
CGImageRef cgimage = CGWindowListCreateImage(CGRectInfinite,
kCGWindowListOptionAll,
kCGNullWindowID,
kCGWindowImageDefault);
NSBitmapImageRep *bitmap_rep = [[NSBitmapImageRep alloc] initWithCGImage:cgimage];
NSImage *image = [[[NSImage alloc] init] autorelease];
[image addRepresentation:bitmap_rep];

[bitmap_rep release];
CGImageRelease(cgimage);
return image;
}

スクリーンキャプチャ画像は後の合成処理がしやすい様に CGImageRef から NSImage へ変換しておく。

先の2つのメソッドから NSImage を取得した後、#compositeToPoint:operation: を使い合成処理を行う。カーソル位置は、キャプチャ直後の座標を NSEvent#mouseLocation から取得して利用している。
- (void)capture
{
NSImage* screen_image = [self screenImage];
NSImage* cursor_image = [self cursorImage];

NSPoint p = [NSEvent mouseLocation];
NSSize s = [cursor_image size];

[screen_image lockFocus];
[cursor_image compositeToPoint:p operation:NSCompositeSourceOver];
[screen_image unlockFocus];
   :
   :



するとこうなる。以下、みやすいようにカーソルの周辺だけに手作業で切り取ってある。


実はマウスカーソルは Safariアイコンの磁石の中心を指していた。合成の結果、マウスカーソルの位置がずれている。これは左下が原点の座標系を使っていることによる。

そこで補正してやる。マウスカーソルの高さの分だけ修正すると次の様になる。
 NSPoint p = [NSEvent mouseLocation];
NSSize s = [cursor_image size];
p.y -= s.height;




いい感じだがまだ少しづれている。今度の原因はマウスカーソルのポイント位置が画像の左上からずれていること。これはマウスカーソル毎に hot spot と呼ばれるオフセット(NSPoint)として定義されている。例えば NSCursor#arrowCursor の場合、画像の左上からカーソルが指す点は (4, 4)だけずれている。


hot spot は NSCursor#hotSpot で取得することができる。

そこでこの (4, 4)を補正してやると:

うまくいった。