ページ

2009年11月16日月曜日

SimpleCap - Mac OS X 10.6.2 で影付きの画像をJPEG保存すると縁が真っ黒になる

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

影のまわりが真っ黒になる

Mac OS X を 10.6.2 にバージョンアップすると SimpleCap で影付きの画像をJPEG保存した時に縁が真っ黒になる現象が出るようになった。PNG、GIFではこの現象は起きない。Tさんからの連絡で気がついた。




原因

以前 GIFで同様の問題が起きていたのを思い出した。
Cocoaの日々: GIF保存
Cocoaの日々: GIF保存(2)

本質的には影というよりはアルファチャネルが使われる半透明の部分を持つ画像の場合にこの現象がおきる。アルファチャネルを持つ画像を -[NSBitmapRep representationUsingType:properties] を使い、GIFで保存するとその領域の背景が黒一色になってしまっていた。10.6.2 以前の場合は JPEG保存だと白の背景色にアルファチャネル部分が合成してくれていたのだが、10.6.2 から GIFと同じ挙動になったようだ。


対応

GIF の時と同様に背景色を白に塗りつぶし、そこへ影付きの画像を合成する方法を取る。既に GIF の時に書いたメソッドがあるのでそれを呼出すだけで済んだ。

bitmap_rep = [self fillBackground:bitmap_rep];

fillBackground: へ影付き(アルファチャネルあり)の画像を渡すと白色で塗りつぶした背景へ合成して返す。実装コードはこんな感じ。

- (NSBitmapImageRep*)fillBackground:(NSBitmapImageRep*)bitmap_rep
{
NSImage *src_image = [[[NSImage alloc] init] autorelease];
[src_image addRepresentation:bitmap_rep];
NSSize image_size = [src_image size];

NSImage *bg_image = [[[NSImage alloc] initWithSize:image_size] autorelease];
[bg_image lockFocus];
[[NSColor whiteColor] set];
[NSBezierPath fillRect:NSMakeRect(0, 0, image_size.width, image_size.height)];
[src_image compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];
[bg_image unlockFocus];
NSBitmapImageRep* output = [[[NSBitmapImageRep alloc] initWithData:[bg_image TIFFRepresentation]] autorelease];
return output;
}


実行してみよう。


直った。

次のバージョンアップ公開時に反映させる予定。
(他のバグFixも遅れに遅れてすみません。今年中には 1.1 をリリースします。。)

- - - - -
今回はブログに開発記録が残っていたおかげで問題が即時に解決できた。