Exception Diary
2009.05.30 [Sat]
_ exifparserに機能追加してみた
(注:tdairy-contrib にある exifparser には、下記の変更をすべて取り込んであります。)
exifparserのコードを読んでみてだいたい様子が分かったので、いくつか機能を追加し、この日記で使い始めている。tDiary Image Galleryのサポート・ページからダウンロードできるものもこのバージョンに変えた。興味のある方はサポート・ページからダウンロードして使って下さい。
exifparserのオリジナル版はsourceforge.jpで公開されているのだが、2003年頃から開発が止まってしまっている。最近気づいたのだが、tDiaryのcontribパッケージにもexifparserがすでに入っていて、こちらはRuby1.8対応の他、GPSタグの処理周りに image_gps.rb の開発者であるkpさんの修正が入っているようだ。このため、今回の機能追加もこちらのほうにマージすることにした。
追加した機能は次の通り。
_ 追加機能1:makenote/nikon2.rbにタグを追加
NikonのMakerNoteタグをいろいろ追加した。NikonのMakerNoteタグについては、以下のサイトを参考にさせて頂いた。
最も実現したかった、"LensParamerers"タグから撮影時のレンズ名を得る機能も実装できた。Nikonの一眼レフデジカメの画像には、撮影時に使用したレンズの情報が入っている。"Lens Parameters"という名前のEXIFタグ(ID=0x0098)がそれなのだが、これはシャッターカウントとカメラのIDを使ってスクランブルされていて、正しい値を得るにはデコードが必要になる。
このデコードのやり方と、結果のデータからレンズ名に変換するするやり方は、C++ライブラリの"exiv2"(http://www.exiv2.org/)のソースを参考にした。C++のコードをほぼそっくりRubyに置き換えただけなのだが、レンズ名への変換テーブルにはNikon純正レンズのほか、SIGMA、TAMRONなどサードパーティー製のレンズがほぼすべて含まれていている。驚くほどの充実ぶり。exiv2開発者の皆さんに深く感謝したい。
新たに実装した "LensParameters" Tag classは、to_s メソッドによりレンズ名を得られるようにしてある。view_exifプラグインも、これを使ってレンズ名を表示するようにした。
_ 追加機能2:Undefined Type タグの扱いの変更
Undefined Type タグのデフォルトの扱いが気に入らなかったので変更した。Undefined Typeタグは「メーカーが独自に決定したデータ形式で格納する」タグという意味である。
(EXIFタグのデータ形式については、前述の「Nikonデジタル一眼レフのメーカーノート」に詳しい。)
オリジナルのexifparserでは、UndefinedタイプのTag classからタグの値をvalueメソッドで読み出すと、ファイルから読み出したデータを無理やり一個のStringに変換したものが返される。Image GalleryのViewerモードでは、すべてのタグ・データの名前と値を表示するようになっているのだが、データによって盛大に文字化けが起こってしまうのはこのせいだった。今回の変更では、Undefined Typeタグのデフォルトの処理が、以下の振る舞いになるようコードを追加した。
- Tag#value(値の読み出し)は、データを各byteごとにIntegerに変換した配列を返すようにする。
- Tag#to_s(Stingへの変換)は、16進数2桁ずつでbyte配列を表すものにする。さらに、データ長が8byte以上の場合は "...(xxxx bytes)" という省略形にする。(例:こちらの"DataDump"というタグなど)
本来、Undefined Typeの場合は、タグごとにそれぞれデータの解釈の仕方が異なるため、それぞれのTag classごとに解釈のためのコードを実装しないといけないはず。なのだが、現在のexifparserにはデフォルトの処理のままになっているUndefined Typeのタグが結構ある。今回の変更ではこのデフォルトの処理を変えることで、今までよりアプリケーションからのUndefined Typeのタグを扱いをやりやすくしたつもり。既存のアプリケーションにちょっと影響を与えるかもしれないが、こちらの方が仕様としては妥当だと思う。
_ このexifparserの扱いを今後どうするか…
まずはtDiaryのcontribパッケージに取り込んでもらうよう、kpさんに持ちかけてみるのがいいんだろうな*1。オリジナルのメンテナンスが止まっているのでいっそメンテナになってしまう、という手もあるけど、全部のカメラメーカーのMekerNoteのメンテナンスはちょっと手に余る気もする。う~む考え中。
ちなみに、この日記では、tDiary Image GalleryでのEXIF表示も、IFDという単位ごとにまとめるようにしてみた。次期バージョンではこの形にする予定。(って、Image Galleryの次期バージョンも進めなきゃな。思い切り横道にそれてる気がするけどやりたいことができたからまぁよい。)
*1 2009.6.6追記:kpさんにメールし、contribパッケージに取り込んでもらった。contribパッケージの全ソースは、codereposのレポジトリで管理されている(http://coderepos.org/share/browser/platform/tdiary)。こちらのコミット権の入手方法もkpさんに教えてもらったので現在申請中。今後は、こちらでメンテナンスしてゆくことにしたい。tDiaryのサイトからダウンロードできるcontribパッケージ(http://www.tdiary.org/download/tdiary-contrib.tar.gz)も、この変更がなされたものになっている。