画像ファイルについて
画像ファイルは特定のフォーマットに応じてバイナリファイルで表現される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でいけた(あまりよくはないだろうが)