|
●概要 EXIF情報を読む方法には二通りある。一つはバイナリファイルを直接読み取る方法*である。もう一つは、GDI+ に標準装備のPropertyItemクラスを利用する方法で、複雑怪奇なメタ構造を持ったEXIF形式を熟知する必要がなく、比較的簡単なコードで実現できるのでお勧めで、このライブラリでも利用している。 *:筆者はその昔、バイナリファイルから読んでいた。しかし、メタデータに完全対応するのが面倒だったので、決め打ち方式で行っていたが、メーカの都合や、メーカ提供のソフトバージョンやファイルバージョンで結構 変更があり、その都度悪戦苦闘していた。やはり、原理的に対応しておくのが結局良い。 ●原理 ○全てを知る その写真にどんな情報があるかは、全てのTag をPropertyIdListで列挙する。そのリストから必要なTagを検索する。 ○特定のアイテムを知る Tag を知りたいアイテムのタグ番号とすれば、 Image.GetPropertyItem(Tag) とすれば、PropertyItem オブジェクトが得られる。 ○PropertyItemクラスの構造 生のEXIFのIFDのディレクトリエントリ に相当する。
●方法(アイテムの獲得) 今、bmpをExifファイルを読み込んだBitmapとすると、先ずは、 ●方法(値の獲得) 個々のPropertyItem の実際の値は、Value なるバイト配列(UByte)として得られる。このままでは、処理ができないので、Type に従って型変換を行い、通常の数値や文字列にする必要がある。 また、EXIFのバイナリ形式は二つの方式がある。ビッグエンディアン(モトローラ形式)とリトルエンディアン(インテル形式)である。これは、一般のバイナリ形式と同じであるが、メーカによって一定しないし、同じメーカでもバージョンによっては変化するし、混在する場合がある。これらは、ファイルのヘッダ部分に記録されているので、それに従って変換処理を行う。 ●分数(表現)の処理 小数点がある数値は分数になっている。(U)Int32の分子と(U)Int32の分母が並んでいる。小数点表現がいい場合と、分数表現がいい場合があるので、Tagによって 以下の切り替えると良い。 ○シャッタ速度 伝統的に、1秒以下の場合は、1/200などと表現する。まさか、0.005秒とは言わない。データとしては、1、200の場合もあるし、10、2000の場合もあるので、
などとする。ただ、データベースでシャッタ速度で検索などするには、時間として浮動小数点で持っていると便利。 ○絞り値 F5.6などと表す。 表現 = "F" + (分子 / 分母).ToString() 'General 形式 で良い。焦点距離なども同じ。General 形式では、少数以下がなければ整数で表現される。大抵は、伝統的な絞り値系列になるようになっている。 ○露出補正値 0.3や -0.7 などと表現する。符号付数値で処理をする。 表現 = (分子 / 分母).ToString() 'General 形式 ○日付 日付は、2005:04:10 11:12:15 のように、年月日部分も":"で区切られている。気持ち悪ければ、"/"で置き換える。DTが元の日付文字列とすれば、共通関数のReplaceで、 DT = Replace(DT, ":", "/", 1, 2, CompareMethod.Text) とすれば良い。上式の 2 は、最初の2箇所のみ置き換えると言う指示。
|