簡體   English   中英

使用 javascript 和 websockets 顯示 blob 中的圖像

[英]Display image from blob using javascript and websockets

我目前正在開發一個 WebSocket 應用程序,該應用程序顯示由 C++ 服務器發送的圖像。 我在那里看到了幾個主題,但我似乎無法擺脫 Firefox 中的這個錯誤:

圖像損壞或截斷:data:image/png;base64,[some data]

這是我用來顯示我的 blob 的 Javascript 代碼:

socket.onmessage = function(msg) {
    var blob = msg.data;

    var reader = new FileReader();
    reader.onloadend = function() {
        var string = reader.result;
        var buffer = Base64.encode(string);
        var data = "data:image/png;base64,"+buffer;

        var image = document.getElementById('image');
        image.src = data;
    };
    reader.readAsBinaryString(blob);
}

我正在使用我在此主題上找到的紅點圖像: https ://stackoverflow.com/a/4478878/1464608 Base64 類來自此處: https : //stackoverflow.com/a/246813/ 1464608

但是我得到的 base64 結果不匹配,Firefox 檢索到我的圖像已損壞的錯誤。

我知道這不是很多信息,但我不知道在哪里看:/任何幫助都非常受歡迎!!

我認為最干凈的解決方案是將 base64 編碼器更改為直接在 Uint8Array 而不是字符串上操作。

重要提示:為此,您需要將 Web 套接字的 binaryType 設置為“arraybuffer”。

onmessage 方法應如下所示:

socket.onmessage = function(msg) {
    var arrayBuffer = msg.data;
    var bytes = new Uint8Array(arrayBuffer);

    var image = document.getElementById('image');
    image.src = 'data:image/png;base64,'+encode(bytes);
};

轉換后的編碼器應如下所示(基於https://stackoverflow.com/a/246813/1464608 ):

// public method for encoding an Uint8Array to base64
function encode (input) {
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    while (i < input.length) {
        chr1 = input[i++];
        chr2 = i < input.length ? input[i++] : Number.NaN; // Not sure if the index 
        chr3 = i < input.length ? input[i++] : Number.NaN; // checks are needed here

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }
        output += keyStr.charAt(enc1) + keyStr.charAt(enc2) +
                  keyStr.charAt(enc3) + keyStr.charAt(enc4);
    }
    return output;
}

你可以寫得更簡單:

socket.onmessage = function(msg) {
   var arrayBuffer = msg.data;
   var bytes = new Uint8Array(arrayBuffer);
   var blob = new Blob([bytes.buffer]);

   var image = document.getElementById('image');

   var reader = new FileReader();
   reader.onload = function(e) {
       image.src = e.target.result;
   };
   reader.readAsDataURL(blob);
};

謝謝,效果很好!!

所以我想我會分享我的最終 javascript 代碼:

var socket = new WebSocket('ws://'+host+':'+port, protocol);
socket.binaryType = 'arraybuffer';

try {
    socket.onopen = function() {
        document.getElementById('status').style.backgroundColor = '#40ff40';
        document.getElementById('status').textContent = 'Connection opened';
    }

    socket.onmessage = function(msg) {
        var arrayBuffer = msg.data;
        var bytes = new Uint8Array(arrayBuffer);

        var image = document.getElementById('image');
        image.src = 'data:image/png;base64,'+encode(bytes);
    }

    socket.onclose = function(){
        document.getElementById('status').style.backgroundColor = '#ff4040';
        document.getElementById('status').textContent = 'Connection closed';
    }
} catch(exception) {
    alert('Error:'+exception);
}

真的不明白為什么 blob 版本如此棘手,但這確實成功了!

感謝其他答案,我設法通過 websocket 接收 jpeg 圖像並將其顯示在新窗口中:

socket.binaryType = "arraybuffer";                 
socket.onmessage = function (msg) 
               {    var bytes = new Uint8Array(msg.data);
                    var blob = new Blob([bytes.buffer]);
                    window.open(URL.createObjectURL(blob),'Name','resizable=1');
                };

另一種選擇

let urlObject;

socket.onmessage = function(msg) {
    const arrayBuffer = msg.data;
    const image = document.getElementById('image');

    if (urlObject) {
        URL.revokeObjectURL(urlObject) // only required if you do that multiple times
    }
    urlObject = URL.createObjectURL(new Blob([arrayBuffer]));

    image.src = urlObject;

};

使用 Blob 非常簡單:

 // Small red dot image const content = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 5, 0, 0, 0, 5, 8, 6, 0, 0, 0, 141, 111, 38, 229, 0, 0, 0, 28, 73, 68, 65, 84, 8, 215, 99, 248, 255, 255, 63, 195, 127, 6, 32, 5, 195, 32, 18, 132, 208, 49, 241, 130, 88, 205, 4, 0, 14, 245, 53, 203, 209, 142, 14, 31, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]); document.getElementById('my-img').src = URL.createObjectURL( new Blob([content.buffer], { type: 'image/png' } /* (1) */) );
 Should display a small red dot: <img id="my-img">

(1) 它也可以在不指定 MIME 類型的情況下工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM