使圖片的 Blob 初始化 HTMLImageElement
前言
最近需要透過 Electron 來讀圖檔後轉成 WebGL 的 Texture ,但這個過程會有問題,Electron 讀檔後的資料型態是 UInt8Array ,本來想得很簡單,透過在如何直接把檔案的 Binary data 給 HTMLImageElement裡所用的方法來餵資料,不幸的有問題,這裡把解決的過程做個紀錄。內容
從 Electron 讀檔後的資料型態為 UInt8Array ,本想編碼成 Base64 後再加上 MIME 的資訊後就能直接初始化 HTMLImageElement ,這個過程的問題是如何從 UInt8Array 裡判斷出 MIME 的資訊,難道要 Parse 裡面的資料嗎? 瀏覽器支援的圖片格式不少,這樣 Parse 的成本實在太高,所以找了一下網路的資料,在HTML – DOWNLOAD IMAGE THROUGH AJAX AND DISPLAY IT 裡發現它透過 Ajax 下載圖檔後,遽然不用 pasre 任何資料就可以初始化 HTMLImageElement ,是如何辦到的呢?它將下載完的 Blob 透過 window.URL.createObjectURL() 回傳的結果就可以直接初始化 HTMLImageElement ,範例如下HTML 的部分
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <input id="btn" type="button" value="go" /> <img id="img"></img> </body> </html>
Javascript的部分
window.onload=function(){ document.getElementById("btn").onclick=function(evt){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState==4 && xhr.status==200) { var imgURL = window.URL.createObjectURL(xhr.response); var img = document.getElementById("img"); img.onload = function(){ window.URL.revokeObjectURL(xhr.response); } img.src = imgURL; // } } xhr.responseType = "blob"; xhr.open("GET","https://i.imgur.com/rPv3FWk.jpg",true); xhr.send(); } }
在 Ajax 下載完後透過 window.URL.createObjectURL() 得到 imgURL ,接著直接拿 imgURL 來初始化 HTMLImageElement ,整個過程相當簡單。 imgURL 的內容是什麼?如果把他列應出來會發現是一個字串!一個類似網址的字串,可以想像是製造一個瀏覽器本地的檔案位置,當 HTMLImageElement 初始化完成後,透過 window.URL.revokeObjectURL() 來取消檔案位址。
開頭說過 Electron 讀檔的資料型態為 UInt8Array,但範例需要的型態是 Blob ,如何轉換呢?可以參考 ArrayBuffer to blob conversion ,過程不會太複雜,範例如下
var blobData=new Blob( [uint8ArrayData] );
要注意的是要用 Array的型態來給,不能省略。
參考資料
[ MDN ] URL.createObjectURL()ArrayBuffer to blob conversion
HTML – DOWNLOAD IMAGE THROUGH AJAX AND DISPLAY IT