NSImageにEXIFをつけてJPEGで保存

お正月からすっかり放置しておりました。放置している間にも色々とイベントが発生したりフラグが立ったり回収されたりしておりましたが、それはまたの機会に時期を逃しつつ情報漏洩していきたいと思います。

閑話休題。 MacでNSImageをJPEG形式で保存するときに、JPEGの圧縮率(画質)を指定しながら画像の回転方向(Tag ID 0112)を付加したいと思ってコードを書いたら、結構な七転八倒だったのでメモを残しておきますよ。

    NSImage *saveImage = 保存したい画像;

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"];
    NSString *exifOriginalDate = [dateFormatter stringFromDate:[NSDate date]];
    NSNumber *exifOrientaion = [NSNumber numberWithInteger:1];
    NSNumber *jpegCompression = [NSNumber numberWithFloat:0.75];

    NSMutableDictionary *metaProperties = [NSMutableDictionary dictionary];
    NSMutableDictionary *tiffProperties = [NSMutableDictionary dictionary];
    NSMutableDictionary *exifProperties = [NSMutableDictionary dictionary];
    [metaProperties setObject:jpegCompression forKey:(NSString *)kCGImageDestinationLossyCompressionQuality];
    [metaProperties setObject:exifOrientaion forKey:(NSString *)kCGImagePropertyOrientation];
    [tiffProperties setObject:exifOrientaion forKey:(NSString *)kCGImagePropertyOrientation];
    [exifProperties setObject:exifOriginalDate forKey:(NSString *) kCGImagePropertyExifDateTimeOriginal];
    [exifProperties setObject:exifOriginalDate forKey:(NSString *) kCGImagePropertyExifDateTimeDigitized];
    [exifProperties setObject:@"Exif user comment" forKey:(NSString *)kCGImagePropertyExifUserComment];
    [metaProperties setObject:tiffProperties forKey:(NSString *)kCGImagePropertyTIFFDictionary];
    [metaProperties setObject:exifProperties forKey:(NSString *)kCGImagePropertyExifDictionary];

    NSMutableData *saveImageData = [[NSMutableData alloc] init];
    CGImageDestinationRef dest = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)(saveImageData), kUTTypeJPEG, 1, nil);
    CGImageRef recViewImageRef = [saveImage CGImageForProposedRect:nil context:nil hints:nil];
    CGImageDestinationAddImage(dest, recViewImageRef, (__bridge CFDictionaryRef)(metaProperties));
    CGImageDestinationFinalize(dest);

    NSString *path = @"~/Desktop/SavedImage.jpg";
    [saveImageData writeToFile:[path stringByExpandingTildeInPath] atomically:YES];

ARCは有効になっていることが前提です。

回転方向、なぜだかオプションの直下とオプションの下のTIFF情報にそれぞれ設定しないと、QuickLookとプレビューの表示に反映されない気がします。(もしかしたら気のせいかもしれません)

ついでにEXIFのタグ一覧を眺めていたら、むむ、Tag ID BC02 も回転方向に関する情報っぽいですね。使っているカメラとかアプリとかあるのだろうか。値の定義がタグ0112と互換が無いようですし。

そして話がややこしいことに、UIImageOrientationの定義がEXIFで定義されている値と互換が無いという…。

コメントを残す