根据您想要的效率轴(带宽与 CPU 效率),我会推荐几种方法。
选项 1:您可以使用画布的 toDataURL 方法。这将返回画布图像数据的 base64 编码图像。它将使用您指定的图像格式(或默认为 PNG)进行压缩,并将预编码为 base64 以通过 WebSocket 发送。
canvas = document.getElementById("mycanvas");
b64png = canvas.toDataURL();
ws.send(b64png);
选项 2:如果您可以容忍有损压缩,那么您可以通过 toDataURL 方法将图像请求为 base64 编码的 JPEG:
canvas = document.getElementById("mycanvas");
b64jpeg = canvas.toDataURL("image/jpeg");
ws.send(b64jpeg);
选项 3:如果您使用的浏览器支持二进制 WebSocket 数据(Chrome、Firefox、IE 10),那么您可以直接通过 WebSocket 发送画布数组缓冲区
canvas = document.getElementById("mycanvas");
ctx = canvas.getContext('2d');
imgdata = ctx.getImageData(0,0, width, height).data; // This is a Uint8ClampedArray
ws.send(imgdata.buffer); // Send the ArrayBuffer from the Uint8ClampedArray
选项 3 可能在带宽方面效率最低,但在客户端和服务器端的处理能力方面效率最高,因为图像数据是原始发送的,几乎不需要预处理/后处理。
带宽效率最高的选项可能是 #2,但在将图像数据转换为 JPEG 格式的过程中,您会损失一些图像质量。您甚至可以更进一步,将数据 base64 解码为数组缓冲区或 blob,然后通过二进制 WebSocket 发送,这样您就不会获得 33% 的 base64 带宽开销,但这会增加更多的 CPU 开销。
如果您想要有效的带宽而不损失任何图像质量,那么选项 #2 是您最好的选择。
一些注意事项/注意事项:
toDataURL 为 base64 数据添加前缀,如下所示:
"data:image/png;base64,iVBORw0KGgoAAAA..."
数据 URL 格式的一个好处是您可以将整个内容粘贴到浏览器地址栏中,然后浏览器将呈现图像。
有关 toDataURL 的更多信息,请参阅MDN 画布页面。