2012/10/10

[php] exif_read_dataでexif情報が取れない!


送られてきたjpg画像をexif情報に合わせて回転させる処理をしていたのだが、なぜか逆さまのまま、回転されなかったものがあった。

回転する条件はexif_read_dataで取得したexif情報に画像の回転に関する情報を表す[Orientation]があった場合のみ。
どの角度に回転するかはimagemagickに任せてた。

調べてみると、Orientationデータなかったので回転させていなかった。
が、直接imagemagickでauto-rotateを実行すると回転する。

imagemagickでorientation情報を取得すると設定されていた。

つまりexif_read_dataでexifの全データを取得することができていなかったようだ。

原因は調査中。
とりあえずはPEARのライブラリを使って試してみようかな
参考:http://lsolesen.github.com/pel/



-- add 2012.11.27

PELというライブラリを使ってみたがエラーになってしまう。
原因を調べて見た。はっきりと理解できてるわけではないので間違いもあるかも…。

exifの回転やシャッタスピードなどのデータが入っている箇所(多分0th IFDのエントリの値)には4バイト以内の値ならそのまま記録して、5バイト以上の値の場合、別の場所に記録しておいて、その別の場所の位置を示す数値が入る(オフセットと呼ぶらしい)。
参考ページ:http://www.ryouto.jp/f6exif/exif.html

今回の画像はここが4バイト以内の値になっている箇所があり、そこでエラーが出てしまっていた。
具体的にはシャッタースピードに関する値で、バイナリエディタで見てみると値はFF FF FF FF。
10進数で表すと4294967295…。
これが仮にシャッタースピードの秒数だったとすると…大体136年分。
136年ちょっとの間カメラのシャッターを開きっぱなしにしている計算になる。
最近になって撮り終わった写真のようなので、シャッターを押したのは136年前の西暦1876年ということになる。
Wikipediaで調べてみるとグラハム・ベルが電話機を発明した年のようだ。
参考ページ:http://ja.wikipedia.org/wiki/1876%E5%B9%B4

ありえない値。
要はここの値は書き換えられていた。
値はなんでもよかったのだと思う。なのでFFで4バイト分埋めたのだろう。

問題はPELというライブラリが、そこの値を実際の値へのオフセットだと決めつけて処理してしまっていたことだ。
恐らくphpのexif_read_dataも同じようなバグなのだと思う。

今回はPELライブラリ内のこの値を読んでいる箇所で、値が異常だと思われる場合は1を代入するように変更した。
厳格なexifデータが必要な処理ではなかったので、とりあえずの対応。

ネットを探しても同じような目にあった人はあまりいないみたい。

0 件のコメント:

コメントを投稿