画像のExifデータの取得方法と取得データの比較 iOS
検証環境
- Xcode 9.2, iOS 11.2 Simulator
- iOS 11.1 iPhone X の背面カメラで撮影したものを AirDrop で Mac に送ってシミュレータ経由で iCloud Photo Library に取り込んだ写真を用いてデータを確認
Exifの取得
まず取得方法をざっくり
Exif等のデータをプロパティとして Core Image
か Image I/O
で取得可能
CoreImage
CIImage *image = [CIImage imageWithContentsOfURL:URL]; NSDictionary<NSString *,id> *properties = image.properties; NSLog(@"%@", properties);
Image I/O + CGImageSourceCopyPropertiesAtIndex
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)URL, nil); NSDictionary *properties = CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(src, 0, nil)); NSLog(@"%@", properties); CFRelease(src);
Image I/O
でメタデータとしても取得可能
Image I/O + CGImageSourceCopyMetadataAtIndex
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)URL, nil); CGImageMetadataRef metadataRef = CGImageSourceCopyMetadataAtIndex(src, 0, nil); NSArray *tags = CFBridgingRelease(CGImageMetadataCopyTags(metadataRef)); for (id tag in tags) { CGImageMetadataTagRef tagRef = (__bridge CGImageMetadataTagRef)tag; CFShow(tagRef); } CFRelease(src); CFRelease(metadataRef);
結果1
CoreImage
と Image I/O + CGImageSourceCopyPropertiesAtIndex
で取得出来る内容は同じ。
ただし後者の CGImageSourceCopyPropertiesAtIndex
の場合は1つのファイルに複数の画像が含まれる画像形式に対応しているので、仮に複数画像が存在して且つ画像毎に取得出来るプロパティが異なっている場合 CIImage
から取得出来るプロパティとどう違いがあるかは検証が必要。(おそらくindex 0の1枚目の画像のプロパティを返すんじゃないかと予想)
以下が取得出来るプロパティのサンプル
Exif data with iOS 11 iPhone X back camera
結果2
Image I/O + CGImageSourceCopyMetadataAtIndex
で取得出来るものは他のものと内容や形式が異なっている。
ちなみに NSArray
のままログ出力すると CFBasicHash
あたりの表示が見辛くなってしまうのでサンプルではfor文で回して CFShow
でタグを1つずつログ出力した。
以下が取得出来るメタデータのサンプル
Metadata with iOS 11 iPhone X back camera
取得データの比較
結果1と結果2を見比べると、ざっと見て結果2の方が数が少なそうに見える。比較して確認してみる。
メタデータのタグに対応するプロパティのキーやデータを探して、対応するものをCSVの別カラムに記載した。(MakerApple のキー2
は512バイトのデータなので記載を省略)
Compare Exif and metadata tag.
補足
- exifEX:PhotographicSensitivity
exifEX:PhotographicSensitivity
はプロパティを見ると対応するものが無いように見える。
ググって見つけたCIPA(一般社団法人カメラ映像機器工業会)に掲載のPDFによると
http://www.cipa.jp/std/documents/e/DC-010-2012_E.pdf
PhotographicSensitivity
は Exif 2.3以降の規格で、Exif 2.21 まで使用されていた ISOSpeedRatings
を代替するものらしい。ISOSpeedRatings
は deprecated との事。
テストに利用した写真の ExifVersion
を見てみると 0221 とあるので、この写真では PhotographicSensitivity
は使用されておらず ISOSpeedRatings
に値が入っていて、タグ取得のAPIではマッピングによりこれを参照しているという事らしい。
- iio:hasXMP
iio:hasXMP
は正確な仕様は不明。
iio
は ImageIO の prefix でApple独自のメタデータタグだと思われる。(ImageIOBase.h を見ると IIO_HAS_IOSURFACE
や IIO_BRIDGED_TYPE
といった定義が見られる。)
名前の通りxmp
のタグが存在しているかどうかを示すものだと推測。
- xmp:CreateDate
- xmp:ModifyDate
- photoshop:DateCreated
先のCIPAのPDFには以下のように掲載されていたので、xmp:CreateDate
と xmp:ModifyDate
はそれをそのまま適用。
DateTimeDigitized = xmp:CreateDate DateTimeOriginal = exif:DateTimeOriginal DateTime = xmp:ModifyDate
またメタデータタグには exif:DateTimeOriginal
が存在しておらず、またプロパティには photoshop:DateCreated
のタグに当てはまるものは無かった。
このタグの扱いをどうしたものかと思っていると CGImageMetadata.h のコメントに以下の記載を発見
- Metadata Working Group guidance is factored into the mapping of CGImageProperties to
- XMP compatible CGImageMetadataTags.
- For example, kCGImagePropertyExifDateTimeOriginal will get the value of the
- corresponding XMP tag, which is photoshop:DateCreated.
という事で、マッピングされているらしい。
よって DateTimeOriginal = photoshop:DateCreated
として適用。
結果より
メタデータタグ CGImageMetadataRef
を使うと exif:Flash
のビットや exif:ExifVersion
の配列を利用しやすい形式に変換してくれたり、マッピングにより Exif のバージョンの違いを吸収をしてくれるという利点がある。
ただし ColorModel
や ProfileName
だったりプライベート仕様の MakerApple
の情報も余す事なく表示したい場合はプロパティを使用する必要がある。
用途に合わせてうまく併用するのが良いかも知れない。