PNG 或 JPG(不是 rgb)通过 websocket 与 ArrayBuffer 没有 base64

PNG or JPG (not rgb) over websocket with ArrayBuffer without base64

有没有一种方法可以将 PNG 图像渲染为 canvas 而无需将其编码为 base64?

服务器以二进制形式发送 PNG,客户端在 ArrayBuffer 中接收它 并将其显示在 canvas 上。我能让它工作的唯一方法是将数据编码为 base64 - 在服务器端 - 因为我需要它更快。在客户端,我创建了一个带有 data:image/png;base64 标签的图像对象。

我知道您可以创建一个 blob 和一个文件 reader 但我无法让它工作。

这是 blob 版本:

var blob  = new Blob([image.buffer],{type: "image/png"});
var imgReader = new FileReader();

imgReader.onload = function (e) {
  var img = new Image();
  img.onload = function (e) {
    console.log("PNG Loaded");
    ctx.drawImage(img, left, top);
    window.URL.revokeObjectURL(img.src);    
    img = null;  
  };

  img.onerror = img.onabort = function () {         
    img = null;
  };
  img.src = e.target.result;              
  imgReader = null;
}
imgReader.readAsDataURL(blob);  

图像是 Uint8Array。我从中创建了一个 blob。其余的不言自明。

图片是正确有效的 PNG 图片。当我从服务器发送它时,我将它们写到服务器端的一个文件中,它们在图像查看器中呈现得很好。

我只见过这种用法。如果你不想通过网络发送base64,那么,你可以在客户端使用btoa将二进制数据转换为base64。

查看 MDN,drawImage takes a CanvasImageSource 对象。 CanvasImageSource 表示 HTMLImageElementImageBitmap 和少数其他类型的任何对象。

进一步搜索,我找到了一些与 ImageBitmap 相关的信息,但不足以提供解决方案。

我本可以将它添加到评论中,但是,它会变成一个巨大的评论并且失去所有的清晰度。

您可以使用 createObjectURL 创建一个 blob url 而无需进行任何 base64 编码,只需将您装箱的 blob 传递给它,您将有一个 url 您可以设置作为 img.src

  var blob  = new Blob([image],{type: "image/png"});
  var img = new Image();
  img.onload = function (e) {
    console.log("PNG Loaded");
    ctx.drawImage(img, left, top);
    window.URL.revokeObjectURL(img.src);    
    img = null;  
  };

  img.onerror = img.onabort = function () {         
    img = null;
  };
  img.src = window.URL.createObjectURL(blob);