Posted at

NSImage/UIImage からビットマップデータを取り出す

More than 3 years have passed since last update.

NSImage または UIImage からビットマップに変換する要件はわりとありそうだけど OSX/iOS がもつ API の柔軟性の高さと複雑さゆえに毎回調べて書いてる気がするので。


OSX (AppKit) の場合

以下のプロセスをたどって変換する。8bits の RGBA 画像を前提としている。MRC で書いてるが ARC を有効にする際は [nsImage release] を消すこと


  • NSImage を使って画像を読み込み

  • ピクセルデータを格納するバッファを確保

  • CGContext を作成

  • NSImage を CGContext に書き込み

  • ピクセルデータを処理

  • 後片付け


NSString *path = /* Take a path to load the file ... */
NSImage *nsImage = [[NSImage alloc] initWithContentsOfFile:path];
if (nsImage != nil) {
NSSize size = [nsImage size];
uint32_t width = (uint32_t) size.width, height = (uint32_t) size.height, components = 4;
uint8_t *pixels = (uint8_t *) malloc(size.width * size.height * components);
if (pixels) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(pixels, width, height, 8, components * width, colorSpace, kCGImageAlphaPremultipliedLast);
NSRect rect = NSMakeRect(0, 0, width, height);
NSGraphicsContext *graphicsContext = (NSGraphicsContext *) [[NSGraphicsContext currentContext] graphicsPort];
CGImageRef cgImage = [nsImage CGImageForProposedRect:&rect context:graphicsContext hints:nil];
CGContextDrawImage(bitmapContext, NSRectToCGRect(rect), cgImage);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorSpace);
/* Handle pixels ... */
free(pixels);
}
}
[nsImage release];


iOS (UIKit) の場合

OSX の場合とほとんど同じだが UIImage から直接 CGImage を取り出す API があるため記述量が少し減る


NSString *path = /* Take a path to load the file ... */
UIImage *uiImage = [[UIImage alloc] initWithContentsOfFile:path];
if (uiImage != nil) {
CGSize size = [uiImage size];
uint32_t width = (uint32_t) size.width, height = (uint32_t) size.height, components = 4;
uint8_t *pixels = (uint8_t *) malloc(size.width * size.height * components);
if (pixels) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(pixels, width, height, 8, components * width, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, width, height), [uiImage CGImage]);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorSpace);
/* Handle pixels ... */
free(pixels);
}
}
[uiImage release];