画像ファイルについて
画像ファイルは特定のフォーマットに応じてバイナリファイルで表現される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
サーバ側
router.get("/test", (req, res, next) => { const options = { url: "http://xxx.png", 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
// 読み込み完了時呼ばれる 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でいけた(あまりよくはないだろうが)