しびら

技術ネタのメモとか。

JavascriptでPNGフォーマットを読み取る

   

今回はJavascriptを使って画像フォーマットの1つであるPNGファイルの情報を一部読み取ってみたいと思います。作っているウェブサービスに必要なものだったので。

PNGのファイルフォーマットは以下のサイトが参考になります。
http://www.setsuki.com/hsp/ext/chunk/IHDR.htm

画像の横幅を取得したい場合は0x0008 (4)ですので0x0008のオフセットに対してUnsigned Int型で取得することで実現できそうです。

実際にバイナリツールの「Bz」を使ってPNGファイルを覗いてみると該当箇所に画像サイズ情報が書かれています。

binary

わかりやすくオレンジの枠で囲っています。「00 00 01 72」= 370px、 「00 00 00 D2」 = 210pxということで、 横370px 高さ210pxの画像であることがわかりますね。

というわけでJavascriptで取得できるかを試そうとしたのですが・・・。

readAsBinaryStringがもう古いらしい

昔バイナリ周りを触っていた時はreadAsBinaryStringを使ってバイナリ操作していた記憶があるのですが、これ素手ラ非推奨になっておりIEではこのメソッド自体が既に消えている模様です。(IEでの動作確認で気づく。)。W3Cからも消されているで消滅するのは時間の問題でしょう。というわけで代わりに使えるreadAsArrayBufferを使いましょう。

参考 :いつの間にかFileAPIのreadAsBinaryStringがオワコンになっていた。今後はreadAsArrayBufferで。

PNGフォーマットの判定を書いてみる

こんな感じでどうでしょう。bin引数はPNGのバイナリデータが入ったArrayBufferです。

横幅を取得してみる

横幅を取得する関数です。Uint32Arrayを使っていたのですが、どうも正しい値を取得してくれない・・・これはリトルエンディアンでバイナリを読み取るための模様。DataViewを使うことで、リトルエンディアン・ビックエンディアンと読み取りを切り替えできるのでこちらを使うことで正しい値を返すことが出来ました。(ただしDataViewは低速らしいですが。)

最後に高さの取得

 

追記(2015/11/24)

  • Int8Array
  • Uint8Array
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array

これらはバイトオーダがCPUネイティブになる(私はIntel CPUを使っていたのでリトルエンディアンとなっていた)らしい? 取得方式がリトルエンディアンかビックエンディアンかを判定する方法がないと取得用途では使えないような・・。

参考:HTML5のJavaScriptでバイナリファイルを扱う(その2)

 

 - Javascript , ,