JavaScript で EXIF を読み取る

HTML と JavaScript 、そしてそれをロードするブラウザだけで──平たく言えばサーバやほかのアプリケーションを用いること無しに、画像ファイルの EXIF 情報を読み取ることができる。ということを知って、試してみた。やや昂奮気味に。

実際の様子は、そのことを知った次のところでデモできるし、コードも示されている。

exif.js が EXIF を読むためのインタフェースで、表向きはそれが主題。でもそこで用いられるライブラリ binaryajax.js 、その中の BinaryFile クラス。これが肝だ。

そのクラスを用いることで、バイナリデータとして、ファイルの内容を読み取るようにすることができる。もちろん対象は EXIF に限らない、つまりファイルならなんでも、そのバイナリ・データにアクセスできる。

そのことは、ここ最近でいちばんの驚きだった。これまでできないと思っていたことが、じつはできたのだ。やろうと思ったひとがいなかっただけだろうか(見かけなかっただけか)、それとも気がつかないうちに、実装されていたんだろうか。

そういえば前の記事に書いたように、 Firefox 3 ではファイルアップロードの仕掛けが変わった。それを調べたときにバイナリデータを取り出せることも、知ることができていたのだけれど、でも Firefox だけのことかなと考えてしまって、それぎり想像を働かせずにしまった。反省すればそれだけ、( JavaScript でバイナリを扱うことは)できないものなんだという思い込みが、あった。

サンプルを見ると難しいことはなさそうで、早速、選択したファイルから EXIF 情報を取り出して、 Google Maps にマーカーを置いてみようと、 GPX Casual Editor に実装を試みることにした。

結局はできたけれど、すんなりとは行かなかった。ひとつは、同ページで示されている exif.js 、このライブラリが汎用的な作りではなく、ちょっとしたアプリケーションになっていること。つまり使い方が限定されているので、少々手を入れなければならなかった。

exif.js そのまま用いるとなると、ページの中に配置した img がロードされたときに( img の onload )、 EXIF 情報を取り出す仕掛けが走り出す、その仕掛けの仕掛け( window の onload )が仕込まれる。ふつうのページなら用は足りるのだけれど、 GPX Casual Editor では、フォームから指定したファイル(や URL からダウンロードしたファイル)から、オン・デマンドに EXIF 情報を取り出したい。だから、仕掛けの部分(イベントの仕掛け)をば、まずはざっくり切り取った。

あとは img の onload と、 img 要素の complete プロパティとの兼ね合いに気をつけて(とくに IE6 )、 EXIF#getData メソッドを扱うように利用すればよいようだ。

そこにも癖があるので、ざっくばらんに言ってしまえば exif.js はそのままだと使いづらいのだけれど、ソースと睨めっこしてみれば、難しいことはなさそうだった。いつか折を見て、汎用的な形に改造したいところではある。

あと file: プロトコルのリクエストについては、 XMLHttpRequest からリクエストを出したとき、その返答の status はゼロになる。

じぶんはそのことを知らなかったため、ハマった。 BinaryAjax の中では status が "200" か "206" かで成功をチェックしていたので、これらに加えて "0" も成功であることを書き加え、そうしてようやくうまくいった、といいたいけれど、 IE6 では意味不明の例外が出て駄目だった。

それも試行錯誤の末に、getResponseHeader("Content-Length") の呼び出しが例外を出すことを突き止め、これをコメント・アウトして対処した。 file: をリクエスト、つまり HTTP していないのだから、 HTTP レスポンス・ヘッダもなにもないのだろう、たぶん。尤も、その機能で得ようとしているのは、 exif.js では利用していないので、コメント・アウトだけで問題なかった。

これでようやくできあがった。

GPX Casual Editor では、フォームのファイル入力はローカル環境で開いたときしか使えない。そのかわり、 URL からも入力できるようにしてある。けれど、その場合はドメインの制約を受ける。 GPX Casual Edior を hwat.sakura.ne.jp 上で試すならば、次の写真画像に EXIF の GPS 情報を書き入れてあるので、それを指定することで試すことができるだろう。

能代風力発電所

能代風力発電所

EXIF 入り画像の URL
http://hwat.sakura.ne.jp/gmapwidget/data/DSCF5851-retouched.JPG

──こうして新しい扉が開いた。 JavaScript だからバイナリは扱えないと諦めていたのは間違いだった。とはいえ、自力ではここまではとても頑張れないので、扉を開いてくれた EXIF および BinaryFile クラスの作者さんには頭が上がらない。

ところで今回は写真画像に含まれている GPS データを読み取ることを試してみたけれど、そもそも GPS データがない写真画像のほうが圧倒的に多いのが現状だ。でもそうした画像でも、撮影時刻はたいてい刻まれている。その撮影時刻と GPS のトラック(軌跡)情報を照らし合わせれば、位置を特定させることができる。むしろじぶんはそれがやりたかったんだ。

トラックバック(2)

GPX Casual Editor を更新しました。 revision 193 では、インポートできるファイルの種類に、 EXIF (JPEG) ファイル... [続きを読む]

先のエントリのとおり、 binaryajax.js を用いれば JavaScript からでもバイナリが読めるのであるからして、画像のタテ、ヨコのピクセル... [続きを読む]

コメントする

広告

Powered by Movable Type 4.261