简体   繁体   English

如何显示来自 WebSocket 二进制数据的图像?

[英]How to display an image from WebSocket binary data?

I am trying to test out Websocketd and hence want to transmit a image in binary我正在尝试测试Websocketd ,因此想要以二进制格式传输图像

My server-side used with websocketd:我的服务器端与 websocketd 一起使用:

#!/bin/bash
xxd -b -g0 dummy.png | awk '{print $2}'

Example output from the command:命令的输出示例:

100010010101000001001110010001110000110100001010
000110100000101000000000000000000000000000001101
010010010100100001000100010100100000000000000000
000000100101100000000000000000000000000110010000
000001000000001100000000000000000000000010000000
000110110000001110101011000000000000000000000000
000110110101000001001100010101000100010100000000
000000000000000011111111111111111111111100011111
000111110001111101011111010111110101111110011111
100111111001111110111111101111111011111111011111
110111111101111101111111011111110111111100111111
001111110011111110101100111110101111100110110010
000000000000000000000000000010010111000001001000
010110010111001100000000000000000000111011000100
000000000000000000001110110001000000000110010101
001010110000111000011011000000000000000000000110
011111110100100101000100010000010101010001111000
100111001110110111011011110011010111001111010011
010001100001100011000111011100010101101101111110
110100111011000100001011010010011110000000101000
000101111110001011100001100010000001100110100000
001111011100011000101101101101001101011110111010
010100111010000001000111010011000000101111101101
000100010001011110011010111000010001100001000011
001110111100110110011111010111010110100110110101
110110100001011111101101001000111000001101110010
010110100110011110111110100111110100001110001000
011111111101100010110001111111011111100011010001
011010101011010110010010000001110000001100000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000001010111010010001
001110110100111110011111001111111111101111100101
010000110001000011111101111101111111010011001101
101100110111011111000101111000001011001111011001
000101111100101100101110100000111001101111111001
111110111110011110101111010111110011110000011000
011111000011011001001011110011100110001110100101
100111011111110001100101100100110110110010100101
100100111110001100001011111011110101111001010010
110101101100001101010010110111011111011101101110
110111011010110110011111111100101101011111000001
011001111011001011100100100110000101101010010101
110101011011001011010001110010100010010011000111
110001010110000001101111111101101110010100110010
111001010001011101101011110111000011110011100101
110011111111101110110011111001001001110000101010
111101011111101110000011001000101011101111110111
011100000110001110001011101101010101000011101010
110001011100011111000001101111010100011101001010
110111010001110011101100110010110111101010011000
111110101100010111001010001101101110101011111000
010000111001000101111101010110100111101110100001
100101000010010110100111011111001001000110111111
100110011101111111111110011101100101000110111101
001011011101110001110101001011110101110011001010
111110100101100011111001000011110101101110011000
100011011011100111011100101100100110111111101110
110010111001001010110011010100000100011101110001
011101001100101111111100101101100101001110110111
111101110110010000111101111001000010101001101100
101000101011011100110110101111101110100011001110
110100101011001110001110000110110110010101100101
101000111101110010001110011000110101001011010110
110000110100001010011101101110111110011100011001
101110111101111011011001101010011001011111011101
010110010111001001100110011100011101001111100111
010111101010111100101101110011011110011100101101
011001010111110110101100100011111010011110101110
010110000011101101110101110101101111110000111010
011010100001101001010110110010101001001000110011
100011111101111111111001110101001111101101100100
110001111110101001000110011001111101011011000011
010011001011110111110010100010101011010111110001
010110100111001110100101100010101100111000101100
001110011010101101111000100110111101101011111001
111110110010110111110011001010010100101101011001
000011110011101101110101001100011111010110110110
011000111010111110011001110011011000011100100101
011001011100100111001001100001001101000101111010
111011011101011111001111000101000101001111001010
011110101101100000011100000011010101110010110001
001001101111111010011000001101001010111001101111
010010000101100101110010110001101110101010100111
011101101001010000000101101000111101100001011100
111011111001101010100100101011001101011110110011
101111001111010010001010001101011111011101110111
001010011110011011010011100100101011001011100100
000011001110001111110111001111010000101010000110
101001001010100100011110011110001010010110101100
100001110110010100111001000010001011100101100010
001011011000001100100001011010010111001111010100
100101010010010101100111000110010110111101010001
011000011011001111001101111101000010011000100001
011001010101011000011110001111000011110000101111
101000101011111110101000111110111101001000010101
011010110111010111101100111111111110011111110110
101001000010101101001011110011100010101011111110
000011001010011111000001111100001001101011101011
100111101001001000110010011010110001110101001100
110101000111011010101111101000101011111100111000
101010010100101011101101100010101011010100001001
111101100000111100111011110111010101001101010010
100101101001110001001101001111000011101010110100
101101100100110000111101011111100100100001011001
011000110001110010001100011001111011100100001010
011110100100010011011011100111100001010001111110
101100011100001000010001101010011111111011010011
010100101001011010011010010011000111110100010101
011001011010110110001111010101010111111111100110
010100100110011011111111010001100111000000001100
101100000101001101010001011001111110010110111010
000100101011011001011000101011011011111011010100
010011010010101101100101110010011100100111110101
111010001001001110111111011111111111111011000110
101011011111110100101101010101010111000010010111
111101010101000101000111011001101001110101111010
101011010101010100011110000010110001010111101101
001001111010100111011111101110100010110111010110
001010001111110010000000001001101101010111011110
010000101100101010010010001100111010101101011110
110101010011111111110101001100101101001000011111
010001011001110110110101010001100101011100111101
111101000100101010011001111001011011011110010110
110100000101100011100110110111101011011001011000
101011011101110110000011110111100111011101001000
010110010111001011000110111001011000011101111110
010110100010110111111011011011011100101000011111
011001101101101100001010001010110101000111010111
010010011100101000011100110101110101101001010010
011000111001100101101001100001110010110101010110
101010110001001010111010010011100101001010010110
100111001000100110111010001111110101001011101010
110001010100010111111001001101101100111110010101
011110011100000110101101000111011010010010011110
010111000100100010011001111000110101101001001011
011010100010110000110011110111111111010010001010
011101011110011011111111111101111010100000101110
010101101001110000100101011001111010101000101110
101101101100110110100010111101110110001110110011
000111110000101100000111101001001111001011111101
011101110110010010011110101001101011010110100100
110001100110101000011110011010111000101111010101
000110101001000011110010011010101011100010010010
101100101110010000001100110101010010011101111011
010101000101110011110110100001110110111010101101
011101010111100010011000010111000001011101001011
110010000011110001001101011010110100100110001101
110101010110110001010010010111101011000110000010
010111011001110100101001010101101001110000100101
011001111010100010010110011011100100101000110011
101011101110101101110110100001010110001010011001
110101100001001000011011011010110110011110011110
111000001111000010001011001101010101011100011011
011011110100011010111001000100010010011011010011
111101010001010001001011110010100111110001110101
011010110100100110001101100101010011010100001111
101101011100010110011010101101100000101101110011
010000111100111010010010001100110101011111111110
101010111001110011101011100100011110001100101010
110001011101001010101101001001010011011011010110
101001001101100111001111010111011000011101100010
111110011111101110110101101100011110111011111110
101010110110110010000110101110101011010110100100
110001100010101001110111100111000100010111111101
110010110111010111011000000011001111110111100011
101110100111101011010101111010100100101011000101
001010100101101111101011100101101101010001011000
011011100110100111101010001110100001010000101011
111010000111011110111101100011101101010010011010
001001100010110010000101101010011100001100110010
001011100101011011011001010110100101001001100011
101110011010010110101111101011101010100111000011
010010001001100000111010100011000001001000101101
010101100011000001110011110101100001001111110101
111111101001001101010010011011010010000100110101
100101101011011100000010011111011111100010010011
110100100111100111111000001000100111010111000111
111101000011111111011100110100010111011011010010
100110010110101001101111101001000011111011111100
110000111001110110100001010100001010110011011110
000001111101001001011010011101011100101000111001
001111101110110110111110011100000000010100111100
111111000000001111101001010101101011000111110100
100101001010000011110111000100101000110101111001
111010001001111111000010101110010110110111101111
100011101000011110111111010001000011001100010101
100010101101010101110111111100010100111110101011
111001100101100010100111010100010110101111001101
101111000011000111111111111100000001011111111111
001001100110000110111111111010110000011000011010
000001100000110110010010100110010110010111100101
001110000000101101010100011100111010110000101100
011010101010110110100001011110101111110110101100
101100010101011011010101110011111110101011011010
101010111011000010100110111101010111100100110101
001010010100101101001101011010111010110011010000
110001011110101001111101110000100110001011010000
000111000001010101000110101011010011010101010100
011011011101010100000011000011111111010110000100
010001010110101110101100110100001110001101111000
011110000011111010111000001110010001010100010110
011001111011111001111010111100100001111010110101
100101100101110010101100111100001000010010110110
001110010001010100100110011001001010100100001001
110011110011010011010111111000110111000111011110
001110101010000111111010101101100010001111110011
001101000100011110000101111011011101011011001010
101111100111011000010110111010100100000111111001
101100111011101001011011110110000011011101110101
010011110100100101011001011100101100001011111101
010110101111110101011110100000111110101100111110
110011000000101010001011100101001111100101000001
001111011001000011000111101000111001011011100011
010011101000010100001101111111010101101011010111
101001110111111011000100001011000011100101011011
111111110001001100110101101010111110010100101011
111000010010001000010000001010011011001111011100
011100100100001110111100010000111011010001011100
101100011000001001101101110110101101110010010000
101100101110010000000100010100111111100001101001
101111010110111111101100011111011100100110010001
010110110110111011011000110100110101101011010111
111000001001001010100011111000001100001000110100
011100111010100111111010110001001001101100011101
010011011100110000011110010000001100101000011010
111111100011101001010110011101110110101101111001
000101111011001110101101101111011010001111001000
101101011110101011001110010100101001001101111001
000010110101101010011001001110010110001111100001
100111111000000111011111100110101011011100101000
011001010000110101111111000111011010101110111011
101101011000001011001011001001001110110111101100
110011100101111010100101001010010110010111001001
110110011011101000010111101110010110100010111010
011011000110101110110111110011011001000110101101
100100011001010011010101110000100000010111010010
110011101101011011110010100010100011010101110011
000101111010100000101110100110111010011110010111
101100101110010001001100111011000011011100100110
011100101110010101010110100111001001101000010111
101111101011010101001101001000110110010110110101
010110010111000000111011000100111000111000011011
001101011010111101011000111001010111011001110110
110101100011110011010110000101100101101011001010
100100101011001101010110010001110100010111110101
011011111011111010110110001111010110000110111111
010001111111000010101111101110110010010001011101
110010101000110011110011110000101011111101110101
110110101101000100010110011111101011000100010110
111010101110010010111110011110011100111011011011
111110111011001011100100100011001001010100111010
011111101111011111110001111100101110000101000110
100111010101110000110100010110011111010100001101
100101010110111100101111001111111111110111100000
001011110111111001001010010110010010110111011011
011100111100101111110001100010110101010110001110
011011000010011111011111010111111110101011100111
001011001111011001100101111010011011000111011111
011100111111101000101110110011101000111010000100
111110110101110111110001000100100100011010111111
010110001000001111010001110001101111110010110001
101100111111110101011001011110100001111010110101
101111110100000001010111001110100000111100101110
101011001110100111001110101111100101110001010000
101011001100000101101100000100110011111110100111
100101001010010100100111111111111110011011001001
100100111111011010010111001011101110111110111100
011111111111001001100011111110110111101110010010
010100100111011001010101100110011111000010011100
010100100000011000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000011101100
111100010011111101110111110101110011001010101111
100010100011011011101101010111000000000000000000
000000000000000001001001010001010100111001000100
10101110010000100110000010000010

I also tried using xxd -b -g0 dummy.png | awk '{print $2}' | tr -d '\\n'我也试过使用xxd -b -g0 dummy.png | awk '{print $2}' | tr -d '\\n' xxd -b -g0 dummy.png | awk '{print $2}' | tr -d '\\n' xxd -b -g0 dummy.png | awk '{print $2}' | tr -d '\\n' for a one-line byte solution but it seems to be a bit too big of a message to transmit (it fails in both the developer mode and in the production try). xxd -b -g0 dummy.png | awk '{print $2}' | tr -d '\\n'用于单行字节解决方案,但它似乎传输的消息有点太大(它在开发人员模式和生产尝试中都失败)。 Instead using the first code the image is transmitted with newlines resulting in a lot of messages in total (see example).而是使用第一个代码,图像用换行符传输,导致总共有很多消息(参见示例)。

Here is my client-side try:这是我的客户端尝试:

<!DOCTYPE html>
<html>
  <head>
    <title>Websocketd image example</title>
    <style>
      #count {
        font: bold 150px arial;
        margin: auto;
        padding: 10px;
        text-align: center;
      }
    </style>
  </head>
  <body>

    <div id="count"></div>
    <div id="img"></div>
    <img id="img2"> </img>

    <script>
      // 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;
}
      var ws = new WebSocket('ws://95.217.6.121/');
      ws.onopen = function() {
        console.log("WS open");
        document.body.style.backgroundColor = '#cfc';
      };
      ws.onclose = function() {
        document.body.style.backgroundColor = null;
        console.log("WS closed");
      };
      ws.onmessage = function(msg) {
        var arrayBuffer = msg.data;
        var bytes = new Uint8Array(arrayBuffer);

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

    </script>

  </body>
</html>

First of all, the data printed out in the console (using console.log(msg.data); ) is ONLY 3 messages, which already is NOT ok.首先,控制台中打印出的数据(使用console.log(msg.data); )只有 3 条消息,这已经不行了。

Secondly and most importantly, the BASE64 value that ends up at the end is wrong.其次也是最重要的是,最后的 BASE64 值是错误的。 How do I fix it?我如何解决它? I tried mendling with the code in the console without any avail.我尝试修改控制台中的代码,但没有任何效果。 Copy-pasting the binary into an online binary to base64 converter and then into the code shows that this method works.将二进制文件复制粘贴到一个在线二进制到 base64 转换器,然后再粘贴到代码中,表明此方法有效。

A simpler solution would be to put this in your server script:一个更简单的解决方案是把它放在你的服务器脚本中:

base64 dummy.png

And this into your onmessage handler并将其放入您的onmessage处理程序中

image.src = 'data:image/png;base64,' + msg.data;

...but I'll try to explain why your solution didn't work anyway. ...但我会尝试解释为什么您的解决方案无论如何都不起作用。


I also tried using xxd -b -g0 dummy.png |我也试过使用 xxd -b -g0 dummy.png | awk '{print $2}' | awk '{print $2}' | tr -d '\\n' for a one-line byte solution but it seems to be a bit too big of a message to transmit tr -d '\\n' 用于单行字节解决方案,但传输的消息似乎有点太大

The problem is the lack of newline at the end of the command's output.问题是命令输出末尾缺少换行符。 As noted in the README , "Any text printed by the process to STDOUT shall be sent as a WebSocket message whenever a \\n newline is encountered." 如自述文件中所述“每当遇到 \\n 换行符时,进程打印到 STDOUT 的任何文本都应作为 WebSocket 消息发送。” ; ; exiting from the server-side script without printing a newline doesn't cause the pending message to be sent.从服务器端脚本退出而不打印换行符不会导致发送挂起的消息。 If you add an echo after the xxd command, the message is received by the browser.如果在xxd命令后添加echo ,则浏览器会收到消息。

First of all, the data printed out in the console (using console.log(msg.data);) is ONLY 3 messages, which already is NOT ok.首先,控制台打印出来的数据(使用console.log(msg.data);)只有3条消息,已经不行了。

I see 23 (collapsed by the console) "000000000000000000000000000000000000000000000000" logs, one "000000000000000000000000000000000000000011101100" log, and 273 RangeError: invalid array length errors from the var bytes = new Uint8Array(arrayBuffer);我看到23(由控制台折叠)“000000000000000000000000000000000000000000000000”日志,一个“000000000000000000000000000000000000000011101100”日志,和273 RangeError: invalid array length的误差从var bytes = new Uint8Array(arrayBuffer); line.线。

This is because you can't pass a string of zeroes and ones to the Uint8Array constructor.这是因为您不能将一串零和一传递给 Uint8Array 构造函数。 An adaptation of this solution to binary would look like this:将此解决方案改编为二进制文件将如下所示:

new Uint8Array(window.cumulativeResponse.match(/.{1,8}/g).map(byte => parseInt(byte, 2)))

Also, if your server sends the data in multiple messages, you have to concatenate them before constructing the base64 image, eg:此外,如果您的服务器在多条消息中发送数据,则必须在构建 base64 图像之前将它们连接起来,例如:

  ws.onopen = function() {
    window.cumulativeResponse = "";
  };
  ws.onmessage = function(msg) {
    window.cumulativeResponse += msg.data;
  };
  ws.onclose = function() {
    let ar = new Uint8Array(window.cumulativeResponse.match(/.{1,8}/g).map(byte => parseInt(byte, 2)));
    document.getElementById('img2').src = 'data:image/png;base64,'+encode(ar);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM