24bitのビットマップ
24bitのビットマップデータを作るにはどうしたら良いかといろいろ試していると
CGImageCreateのbitmapInfoの指定で24bitのビットマップができた。
CGImageCreate
Creates a bitmap image from data supplied by a data provider. CGImageRef CGImageCreate ( size_t width, size_t height, size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGColorSpaceRef colorspace, CGBitmapInfo bitmapInfo, CGDataProviderRef provider, const CGFloat decode[], bool shouldInterpolate, CGColorRenderingIntent intent );
動作確認用のテストプログラム
-(void)bitmapTest2:(NSString*)fname { //------------------------------------------------------------ // ◆デスクトップのスクリーンショットを取得 //------------------------------------------------------------ // Available in Mac OS X v10.5 and later CGImageRef screenImageRef = CGWindowListCreateImage( [[NSScreen mainScreen]frame], kCGWindowListOptionOnScreenBelowWindow, kCGNullWindowID, kCGWindowImageDefault); int width = CGImageGetWidth(screenImageRef); int height = CGImageGetHeight(screenImageRef); NSLog(@"width : %d",width) ; NSLog(@"height : %d",height) ; unsigned char *data = malloc(width * height * sizeof(unsigned char) * 4); CGContextRef bitmapContext = CGBitmapContextCreate(data, width, height, 8, width * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast); CGContextDrawImage(bitmapContext, CGRectMake(0,0,width,height), screenImageRef); unsigned char *bitmap = CGBitmapContextGetData(bitmapContext); CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL, bitmap, width * height * 4, NULL); CGImageRef imageRef = CGImageCreate(width, // width height, // height 8, // bitsPerComponent 32, // bitsPerPixel width * 4, // bytesPerRow CGColorSpaceCreateDeviceRGB(), // colorspace kCGBitmapByteOrderDefault, // bitmapInfo ※この指定で24ビットのビットマップになる dataProviderRef, // provider NULL, // decode NO, // shouldInterpolate kCGRenderingIntentDefault); // intent CGImageAlphaInfo info = CGImageGetAlphaInfo(imageRef); if(info == kCGImageAlphaNone) NSLog(@"info : kCGImageAlphaNone") ; if(info == kCGImageAlphaPremultipliedLast) NSLog(@"info : kCGImageAlphaPremultipliedLast") ; if(info == kCGImageAlphaPremultipliedFirst) NSLog(@"info : kCGImageAlphaPremultipliedFirst") ; if(info == kCGImageAlphaLast) NSLog(@"info : kCGImageAlphaLast") ; if(info == kCGImageAlphaFirst) NSLog(@"info : kCGImageAlphaFirst") ; if(info == kCGImageAlphaNoneSkipLast) NSLog(@"info : kCGImageAlphaNoneSkipLast") ; if(info == kCGImageAlphaNoneSkipFirst) NSLog(@"info : kCGImageAlphaNoneSkipFirst") ; //------------------------------------------------------------ // ◆ファイル出力 //------------------------------------------------------------ // ビットマップを作成 NSBitmapImageRep* bitmap_rep = [[NSBitmapImageRep alloc]initWithCGImage:imageRef] ; // このビットマップは24ビットになる NSLog(@"bitmap_rep.bitsPerPixel : %d",bitmap_rep.bitsPerPixel) ; NSLog(@"bitmap_rep.bytesPerPlane : %d",bitmap_rep.bytesPerPlane) ; NSLog(@"bitmap_rep.bytesPerRow : %d",bitmap_rep.bytesPerRow) ; NSLog(@"bitmap_rep.numberOfPlanes : %d",bitmap_rep.numberOfPlanes) ; NSLog(@"bitmap_rep.samplesPerPixel : %d",bitmap_rep.samplesPerPixel) ; // ファイル出力 [self writeImageFileName:fname BitmapImageRep:bitmap_rep] ; //------------------------------------------------------------ // 後処理 //------------------------------------------------------------ free(data); CGDataProviderRelease(dataProviderRef); CGImageRelease(imageRef); CGImageRelease(screenImageRef); [bitmap_rep release] ; }
テストプログラムの実行結果
CGImageCreateのbitmapInfoにkCGBitmapByteOrderDefaultを指定した場合の実行結果
2009-11-23 20:19:37.870 ImageTest[2148:a0f] width : 1680 2009-11-23 20:19:37.873 ImageTest[2148:a0f] height : 1050 2009-11-23 20:19:37.910 ImageTest[2148:a0f] info : kCGImageAlphaNone 2009-11-23 20:19:37.911 ImageTest[2148:a0f] bitmap_rep.bitsPerPixel : 24 2009-11-23 20:19:37.911 ImageTest[2148:a0f] bitmap_rep.bytesPerPlane : 5292000 2009-11-23 20:19:37.912 ImageTest[2148:a0f] bitmap_rep.bytesPerRow : 5040 2009-11-23 20:19:37.912 ImageTest[2148:a0f] bitmap_rep.numberOfPlanes : 1 2009-11-23 20:19:37.913 ImageTest[2148:a0f] bitmap_rep.samplesPerPixel : 3
imageRefのCGImageAlphaInfoを確認するとkCGImageAlphaNoneになっている。
2009-11-23 20:19:37.910 ImageTest[2148:a0f] info : kCGImageAlphaNone
NSBitmapImageRepのbitsPerPixel(bitmap_rep.bitsPerPixel)は、24になっている。
2009-11-23 20:19:37.911 ImageTest[2148:a0f] bitmap_rep.bitsPerPixel : 24
bitmap_rep.bytesPerRowは、画像の幅1680 × 3の5040と一致している。
この結果を見ると、24bitのビットマップが作成されているようだ。
とりあえず、この方法で進めてみよう。
2009.12.15追記
上記のプログラムでは、作成したビットマップデータはおかしくなっているかも?