プログラミング > その他 >

Exifについて

2023-04-01

目次

JPEGの中身

   JPEG (Joint Photographic Experts Group) を開くと画像が表示される。それは人が見るために可視化したもの。実際にはバイナリデータと呼ばれるコンピュータが読み取るための文字列で構成されている。
   コンピュータがバイナリデータ (0と1の2文字の組み合わせ) を認識する単位は1バイト (8ビット) のため、表現される文字パターンは28ある。これはちょうど162である。そのため16進数を2文字で1バイトを表すことができる。また、人にとっても8桁のデータを見るより2桁の方が見やすい。
   JPEG画像データの先頭には\xff \xd8というデータがある。「\x」はバイナリデータであることを表していて、その後に続く2文字がデータとなる。この場合は0からfまでの16進数で表している。

JPEGの構造

   JPEGにはこれからどんなデータが続くのかを表す「マーカ」がある。マーカは2バイトで表される (表1) 。
表1. JPEGのマーカ
マーカ名 (バイナリ表示) 意味
SOI (Start of Image) \xff \xd8 JPEGデータの始まり
APP (application data) \xff \xe0〜\xff \xef メイン画像データ以外のデータ
SOF (Start of Frame) \xff \xc0〜\xff \xc2 ハフマン関連
DQT (Define Quantization Table) \xff \xdb ハフマン関連
DHT (Define Huffman Table) \xff \xc4 ハフマン関連
DRI (Define Restart Interval) \xff \xdd データ欠損時の修復用?
SOS (Start of Scan) \xff \xda メイン画像データの始まり
EOI (End of Image) \xff \xd9 JPEGデータの終わり
   「SOI」「SOS」「SOE」以外のマーカにはマーカを表す2バイトの続きにそれぞれ定義された情報が入っている。マーカの後の2バイトにはデータの長さの情報があり、n+2の長さを表している。+2されているのはデータの長さを表す分も合わせているから。ExifなどのデータはAPP (メイン画像データ以外のデータ) に含まれており、例えば\xff \xe1 \x04 \x10...とあれば、\x04 \x10がデータの長さを表していて数値にすると1040なのでこのあとに1038バイトの情報が記述されていることがわかる。下図はこれから説明するJPGE構造の概要 (図1) 。
図1. JPEGの構造の概要。

Exifの規格

   Exif (Exchangeable image file format) はCIPA (一般社団法人カメラ映像機器工業会, Camera & Imaging Products Association) がJEITA (社団法人電子情報技術産業協会, Japan Electronic Industry Development Association) と共同で策定したもの。
   ExifはAPP内に挿入され、TIFF (Tag Image File Format) で使われているIFD (Image File Directory) 形式によって詳細にデータが区分されている。データの並びは「APPマーカ」「データの長さ」「Exif」「TIFF header」「0th IFD」「Exif IFD」「GPS IFD」 (「1st IFD」「JPEG Thumbnail」) で構成されている。Exif2.3の規格によれば圧縮サムネイルファイルがあると2個目のIFD「1st IFD」を追加する。
   「TIFF header」は12バイトで構成され、この中に二つの重要な情報がある。
   1つ目は3~4バイトにエンディアンと呼ばれるものがあり、CPUに依存してバイナリデータの読む向きが変化する。例えば「\x00 \x01」を数字にしたとき1と読み込むのはビッグエンディアン、逆さまにして「\x01 \x00」として257と読むのがリトルエンディアン。3~4バイトが\x4D \x4Dならビッグエンディアン、\x49 \x49ならリトルエンディアン。ASCII (American Standard Code for Information Interchange) で表すとそれぞれ「MM」「II」になる。
   2つ目は11~12バイトにTag数と呼ばれるものがある。tag数以降に「フィールド」と呼ばれる12バイトの塊がいくつあるのかを示している。tag数が10なら12バイトのフィールドが10個存在することになる。フィールド内には4つの「Tag」「Type」「Count」「Value Offset」という区分がある。「Tag」は何のフィールドかを表す固有の値で2バイト、「Type」は整数値やASCIIなどデータの種類を決定する値で2バイト、「Count」はデータの数を表し4バイト、「Value Offset」は実際にデータがある場所までの距離を表し4バイト、フィールドは合計で12バイトという構成になっている。「Value Offset」の4バイト内にデータを入れられる場合「Value Offset」は距離ではなく値が入る。「Type」がBYTE、SHORT、LONG、SLONGのどれかで「Count」が1の場合、「Type」がASCIIまたはUNDEFINEDで「Count」が4以下の場合である。その他は「Value Offset」で表される距離からデータが始まる。「Value Offset」のゼロ点はエンディアンが始まる位置である。

0th IFD

   TIFF headerの後「0th IFD」が続く。「0th IFD」の中にはカメラ撮影時の情報やGPS情報がある。特にGPS情報はリスクが大きいので注意が必要。GPS情報はどこで撮影したのかわかるため思い出として残る。一方、デジタル機器の発展に伴い簡単にネットワーク上に画像をアップロードできるようになったためGPS情報の取り扱いが難しくなっている。というのも自宅で撮影したものの場合GPS情報は当然自宅なのである。出先で撮影したものならば観光地で撮影した写真とわかる。しかし、GPS情報が住宅街で屋内写真を撮っていた場合、自宅である可能性が高くなる。これは個人情報の特定に繋がってしまうので注意が必要ということ。
   さて「0th IFD」の中身は「Tag」「Type」「Count」「Value Offset」で1つのフィールドがいくつか並んでいる。以下はある写真に入っていた内容 (表2) 。
表2. 0th IFD
Tag (バイナリ表示) Type Count Value Offset
画像入力機器のメーカ名 \x01 \x0f ASCII 6 122
画像入力機器のモデル名 \x01 \x10 ASCII 25 128
画像方向 \x01 \x12 SHORT 1 1
画像の幅の解像度 \x01 \x1a RATIONAL 1 154
画像の高さの解像度 \x01 \x1b RATIONAL 1 162
画像の幅と高さの解像度の単位 \x01 \x28 SHORT 1 2
ファイル変更日時 \x01 \x32 ASCII 20 170
Exif IFDへのポインタ \x87 \x69 LONG 1 190
GPS IFDへのポインタ \x88 \x25 LONG 1 854

Exif IFD

   「0th IFD」のオフセット値から移動したらまず2バイトでフィールドの数が示されている。そしてその後に、示された数だけ12バイトのフィールドが続く。以下はある写真に入っていた内容 (表3) 。
表3. Exif IFD
タグ (バイナリ表示) タイプ カウント オフセット
露出時間 \x82 \x9a RATIONAL 1 652
Fナンバー \x82 \x9d RATIONAL 1 660
露出プログラム \x88 \x22 SHORT 1 2
撮影感度 \x88 \x27 SHORT 1 100
感度種別 \x88 \x30 SHORT 1 2
推奨露光指数 \x88 \x32 LONG 1 100
Exifバージョン \x90 \x00 UNDEFINED 4 25443
原画像データの生成日時 \x90 \x03 ASCII 20 668
ディジタルデジタルデータの作成日時 \x90 \x04 ASCII 20 688
各コンポーネントの意味 \x91 \x01 UNDEFINED 4 1026
シャッタースピード \x92 \x01 SRATIONAL 1 732
絞り値 \x92 \x02 RATIONAL 1 740
露光補正値 \x92 \x04 SRATIONAL 1 748
レンズ最小F値 \x92 \x05 RATIONAL 1 756
測光方式 \x92 \x07 SHORT 1 5
フラッシュ \x92 \x09 SHORT 1 0
レンズ焦点距離 \x92 \x0a RATIONAL 1 764
DataTimeのサブセック \x92 \x90 ASCII 3 13875
DataTimeOriginalのサブセック \x92 \x91 ASCII 3 13875
DataTimeDigitizedのサブセック \x92 \x92 ASCII 3 13875
対応フラッシュピックスバージョン \xa0 \x00 UNDEFINED 4 24673
色空間情報 \xa0 \x01 SHORT 1 1
実効画像幅 \xa0 \x02 LONG 1 1024
実効画像高さ \xa0 \x03 LONG 1 768
焦点面の幅の解像度 \xa2 \x0e RATIONAL 1 772
焦点面の高さの解像度 \xa2 \x0f RATIONAL 1 780
焦点面解像度単位 \xa2 \x10 SHORT 1 2
個別画像処理 \xa4 \x01 SHORT 1 0
露出モード \xa4 \x02 SHORT 1 0
ホワイトバランス \xa4 \x03 SHORT 1 0
デジタルズーム倍率 \xa4 \x04 RATIONAL 1 788
撮影シーンタイプ \xa4 \x06 SHORT 1 0
カメラシリアル番号 \xa4 \x31 ASCII 13 796
レンズの仕様情報 \xa4 \x32 RATIONAL 4 810
レンズシリアル番号 \xa4 \x35 ASCII 11 842

GPS IFD

   「GPS IFD」も「Exif IFD」と同様に2バイトでフィールドの数が表される。経度と緯度の値が上記のリスクに当たる場所。以下はある写真に入っていた内容 (表4) 。
表4. GPS IFD
タグ (バイナリ表示) タイプ カウント オフセット
GPSタグのバージョン \x00 \x00 BYTE 4 515
北緯 (N) or 南緯 (S) \x00 \x01 ASCII 2 19968
緯度 (数値) \x00 \x02 RATIONAL 3 968
東経 (E) or 西経 (W) \x00 \x03 ASCII 2 17664
軽度 (数値) \x00 \x04 RATIONAL 3 992
高度の基準 \x00 \x05 BYTE 1 0
高度 (数値) \x00 \x06 RATIONAL 1 1016
GPS受信機の状態 \x00 \x09 ASCII 2 16640
測位に用いた地図データ \x00 \x12 ASCII 7 1024

参考