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];