画像ファイルについて
画像ファイルは特定のフォーマットに応じてバイナリファイルで表現されるhttp://www.setsuki.com/hsp/ext/png.htm
例えばpngファイルをテキストエディタで開いてみると
âPNG ... IHDR ....
というふうになっているBase64について
一部の言語・環境ではバイナリの対応が微妙。特にhttp通信時は直接バイナリのやりとりができない(はず)ので
base64で変換(エンコード)する必要がある。
受け取り側で自動でデコードされたりbase64のまま使えたりするケースがある。
例えばGET,POST時のパラメータはブラウザからエンコードして送ってもサーバ側でデコードする必要がなかったり
imgタグのsrcは画像ファイルのパスだけでなくbase64でエンコードされた文字列をそのまま使用することもできる。
Node.js のrequestはバイナリを取得する場合、
encodingにnullを設定する。
以下の2/3あたりに記述がある。
https://github.com/request/request
imgタグのsrcは
ファイル名だけでなく
data url scheme という形式で表現できる
http://d.hatena.ne.jp/moogme/20090814/p3
<img src="data:image/png;base64,{base64 encoded data}">
以下で実際に画像を変換できる
https://syncer.jp/base64-encoder
javascript レスポンスタイプをblob形式でリクエストを送ることでバイナリで受け取ることができる
http://kinjouj.github.io/2013/04/xmlhttprequest-load-image-binary.html
http://qiita.com/Yarimizu14/items/f56123c738f12ad1844a
実装例
実装例としてとあるURL http://xxx.png から画像ファイルを取得して、ブラウザに表示(imgタグ)ということをやってみる。
サーバ環境はNode.js
サーバ側
1 2 3 4 5 6 7 8 9 10 11 12 | router.get( "/test" , (req, res, next) => { const options = { method: "GET" , encoding: "null" , } request(options, (error, response, body) => { const result = `data:image/jpeg;base64,${ new Buffer(body).toString( "base64" )}` }) res.send(result) }) |
encodingをnullにしてバイナリを取得できるように。
バイナリを取得した後はImgタグ用に変換。base64形式で変換した後先頭に"data:image/jpeg;base64,"を追加している。
クライアント
html
head ...
body ...
<img id="thumbnail" src="" >
表示用にimgタグを記述。それ以外は省略。
js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 読み込み完了時呼ばれる window.addEventListener( "load" , (e) => { const xhr = new XMLHttpRequest() const async = true xhr.open( "GET" , "/test" , async) xhr.onreadystatechange = () => { switch (xhr.readyState) { case 0: console.log( "uninitialized!" ) break case 1: console.log( "loading..." ) break case 2: console.log( "loaded." ) break case 3: console.log( "interactive... " ) break case 4: if (xhr.status === 200 || xhr.status === 304) { // ここでImgタグに戻り値を入れる document.getElementById( "thumbnail" ).src = xhr.response } else { console.log( "Failed. HttpStatus: " + xhr.statusText) } break default : console.log( "error nop default" ) } } xhr.send() } |
サーバ側で適切にbase64エンコードで出来ていればXMLHttpRequest でリクエストを投げて戻ってきた値をimgタグのsrcへ直接入れるだけでいい。
このままでは動かないと思うけど大体こんなイメージ。
ちなみにPNG画像でもdata:image/jpeg;base64でいけた(あまりよくはないだろうが)