使用 javascript 和 websockets 显示 blob 中的图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11089732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Display image from blob using javascript and websockets
提问by guitio2002
I'm currently working on a WebSocket application that is displaying images send by a C++ server. I've seen a couple of topics around there but I can't seem to get rid of this error in Firefox:
我目前正在开发一个 WebSocket 应用程序,该应用程序显示由 C++ 服务器发送的图像。我在那里看到了几个主题,但我似乎无法摆脱 Firefox 中的这个错误:
Image corrupt or truncated: data:image/png;base64,[some data]
图像损坏或截断:data:image/png;base64,[some data]
Here's the Javascript code I'm using to display my blob:
这是我用来显示我的 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);
}
I'm using the image of a red dot that I found on this topic: https://stackoverflow.com/a/4478878/1464608And the Base64 class is from here: https://stackoverflow.com/a/246813/1464608
我正在使用我在此主题上找到的红点图像:https://stackoverflow.com/a/4478878/1464608 Base64 类来自此处:https: //stackoverflow.com/a/246813/ 1464608
But the base64 outcome I get doesn't match and Firefox retrieves me an error of the image being corrupted.
但是我得到的 base64 结果不匹配,Firefox 检索到我的图像已损坏的错误。
I know this ain't much informations but I don't have a clue where to look :/ Any help is more than welcome!!
我知道这不是很多信息,但我不知道在哪里看:/任何帮助都非常受欢迎!!
回答by Stefan Haustein
I think the cleanest solution would be to change the base64 encoder to operate directly on a Uint8Array instead of a string.
我认为最干净的解决方案是将 base64 编码器更改为直接在 Uint8Array 而不是字符串上操作。
Important: You'll need to set the binaryType of the web socket to "arraybuffer" for this.
重要提示:为此,您需要将 Web 套接字的 binaryType 设置为“arraybuffer”。
The onmessage method should look like this:
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);
};
The converted encoder should then look like this (based on https://stackoverflow.com/a/246813/1464608):
转换后的编码器应如下所示(基于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;
}
回答by Nikita Koksharov
You may write it much simpler:
你可以写得更简单:
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);
};
回答by guitio2002
Thanks, it's working great!!
谢谢,效果很好!!
So I figure I'd share my final javascript code:
所以我想我会分享我的最终 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);
}
don't really understand why the blob version is so tricky but this did the trick!
真的不明白为什么 blob 版本如此棘手,但这确实成功了!
回答by Walle Cyril
Another alternative
另一种选择
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;
};
回答by J.Jacobs-VP
Thanks to the other answers, I managed to receive a jpeg image by websocket and display it in a new window :
感谢其他答案,我设法通过 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');
};