2019年8月26日 星期一

使圖片的 Blob 初始化 HTMLImageElement

使圖片的 Blob 初始化 HTMLImageElement

前言

  最近需要透過 Electron 來讀圖檔後轉成 WebGL 的 Texture ,但這個過程會有問題,Electron 讀檔後的資料型態是 UInt8Array ,本來想得很簡單,透過在如何直接把檔案的 Binary data 給 HTMLImage​Element裡所用的方法來餵資料,不幸的有問題,這裡把解決的過程做個紀錄。

內容

  從 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

相關文章

如何直接把檔案的 Binary data 給 HTMLImage​Element

沒有留言:

張貼留言