Bezelボタンを作る[12]画像をグレースケールで表示する(その2)

2010年6月26日土曜日 | Published in | 0 コメント

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

[前回]

以前紹介した画像をグレースケール変換して表示する方法が、Alphaチャネル(半透明マスク)に対応していないことがわかった。

透明部分が黒くなる


以前は背景が白い画像を使っていたので気がつかなかったのだが、背景が透明な画像をグレースケール変換するとその部分が黒くなってしまうことがわかった。

元画像の例。図ではわからないが周りの部分が透明になっている。
これを前回の方法でグレースケール変換するとこうなる。
周りの透明部分が黒くなってしまっている。これはグレースケール変換用に作成した CGBitmapContextCreate() の引数で kCGImageAlphaNone を渡していたため。この引数は Alphaチャネルを持たないことを示している。
CGContextRef context = CGBitmapContextCreate(
             nil, image.size.width, image.size.height, 8, 0,
             colorSpace, kCGImageAlphaNone);



Alphaチャネルの合成


これを解決するには透明部分、すなわちAlphaチャネルのみを取り出した画像を作り、これをマスク情報として前回の画像に合成してやれば良い。

Alphaチャネルの画像は CGBitmapContextCreate() の引数に kCGImageAlphaOnly を渡すと作ることができる。
先の例の画像の場合、Alphaチャネルはこんな感じになる。
白い部分が透明で、黒い部分が不透明をな領域を表している。

合成には CGImageCreateWithMask() が使える。

最終的なソースコードはこんな感じ
-(UIImage*)convertGrayScaleImage:(UIImage*)image
{
 CGRect rect = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
 
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
 
 // (1) create alpha chanel
 CGContextRef alphaContext = CGBitmapContextCreate(
   nil, image.size.width, image.size.height, 8, 0,
   colorSpace, kCGImageAlphaOnly);
 CGContextDrawImage(alphaContext, rect, [image CGImage]);
 CGImageRef alphaImage = CGBitmapContextCreateImage(alphaContext);
 CGContextRelease(alphaContext);
 
 // (2) create gray scale image
 CGContextRef context = CGBitmapContextCreate(
   nil, image.size.width, image.size.height, 8, 0,
   colorSpace, kCGImageAlphaNone);
 CGContextDrawImage(context, rect, [image CGImage]);
 CGImageRef grayScaleImage = CGBitmapContextCreateImage(context);
 CGContextRelease(context);
 
 // (3) composite images
 UIImage* grayScaleUIImage = [UIImage imageWithCGImage:
          CGImageCreateWithMask(grayScaleImage, alphaImage)];
 
 CGImageRelease(grayScaleImage);
 CGImageRelease(alphaImage);
 CGColorSpaceRelease(colorSpace);
 
 return grayScaleUIImage;
}


さて実行してみよう。
背景が透明になった。


参考情報


iPhoneアプリ開発、その(185) 出るもんが出たか…|テン*シー*シー
kCGImageAlphaOnly と CGImageCreateWithMask() について参考になった。

Responses

Leave a Response

人気の投稿(過去 30日間)