LoginSignup
14
14

More than 5 years have passed since last update.

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

Posted at

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14