2013-12-27

RICOH THETAで撮影した360°画像をthree.jsで全天球処理したついでにFileAPIのDrag&Drop対応してみた

職場の同僚がRICOH THETAなる360°写真が撮影できるカメラを買って、何やら面白そうなことをやりたがってたので、three.jsを使って全天球処理するところを手伝いました。
全天球処理はさほど難しくなかったのですが、欲を出して行ったDrag&Drop処理が結構ハマったので、その辺りを話ます。

下のDEMOサイトにTHETAで撮影した画像をDrag&Dropすると、いい感じに全天球にしてくれます。ソースコードもすべてGithubに公開してますので参考にしてください。

目次

  1. RECOH THETAとは
  2. three.jsでの全天球処理
  3. HTML5 File APIによるDrag&Drop処理
  4. Cross Origin image load HACK
  5. まとめ

1. RECOH THETAとは

RICOH THETAとはRICOH社が製造する360°写真が撮影できるカメラです。

外見がシャレてます。でも結構お高いです。(¥44,800 執筆時)

しかも、公式サイトもおしゃれで流行の縦スクロール型のレスポンシブデザインですが、中身はHTML5ではなくXHTMLでした。残念w。

スクロールで動く部分はjQueryPluginsではなく、手組っぽいです。

2. three.jsでの全天球処理

three.jsでの全天球処理はこちらのWebGLサンプルを参考にしました。
(とは言ってもほとんどコピペですが・・・)

http://threejs.org/examples/webgl_panorama_equirectangular.html

全天球処理がさくっと終わったので、欲を出してimageファイルをDrag&Dropしてthree.jsのテクスチャを変えようとおもったのですが、これがハマりました。

3. HTML5 File APIによるDrag&Drop処理

HTML5にはFIleAPIという、ブラウザからローカルファイルのやり取りができる標準APIがあります。今回はFlieAPIを使ってimageファイルのDrag&Drop処理を実現していきます。

処理の大枠は次のようなコードになります。

実装時の注意点としては、ファイルドロップ時にイベントの伝搬をキャンセルしないと、ブラウザでimageファイルを開いてしまいます。

4. Cross Origin image load HACK

実際にドラックされたimageファイルはdataURI形式に変換して、three.jsのテクスチャに設定すればうまく行くと思ったのですが、dataURIを読み込む際に同一生成元ポリシー(same origin policy)に抵触していまいエラーとなってしまいました。

dataURIは、通常のWebのリソース命名方式(httpとか)ではなく、独自の命名方式(data)で命名されてしまうため、ドラッグしたimageファイルをJavascriptで再利用しようとすると必ず同一生成元ポリシー違反となってしまいます。
RFC6454 — The Web Origin Conceptの仕様書に書いてありました。)

そのため一度、ダミーのimgタグに紐づけてから再利用するようなHACKを行う必要があります。

これで、RICOH THETAで撮影した画像をDrag&Dropすると、three.jsでいい感じに全球体処理してくれます。three.jsすごい!

5. まとめ

three.jsはやってて面白いですね。

HTML5のfileAPIを使うことで、ブラウザ上でローカルファイルを扱うことが簡単になってきましたが、それをjavascriptで再利用する際は、いろいろ問題があることも分かりました。

いつになったら、Webはこういうハックとかバッドノウハウが無い世界になるのでしょうか・・・まだまだ苦難の時代は続きそうです。

X. 参考資料

p.s

同僚がRICOH THETAの競合製品を見つけて悶絶していましたw
こちらはウェアラブルです。しかもサイトはしっかりHTML5でした。もっと頑張れRICOH

http://bublcam.com/