HTML5将png缓冲区加载到画布中(用于流式传输)

Gb0*_*b01 5 javascript streaming html5 buffer html5-canvas

通过websocket,我检索PNG格式的图像的二进制缓冲区(类似的东西).

我想将此PNG缓冲区加载到画布中,然后读取不同的像素以读取未压缩的数据.

我设法做到了,但这是愚蠢的:

function onBinaryMessage(/*ArrayBuffer*/ input) {
  input = new Uint8Array(input);

  var str = '';
  for (var i = 0; i < input.byteLength; i++)
    str = str + String.fromCharCode(input[i]);

  var image = document.getElementById("image");
  image.src = 'data:image/png;base64,' + btoa(str);

  var c = document.getElementById("canvas");
  var ctx = c.getContext("2d");
  ctx.drawImage(image, 0, 0);
  var imgData = ctx.getImageData(0, 0, image.width, image.height);
  console.log(imgData);
}
Run Code Online (Sandbox Code Playgroud)

我必须将我的二进制文件转换成一个字符串来编码64这个字符串,而不是我影响我的图像src到这个新创建的encoded64字符串...浏览器必须将这个编码的64数据重新转换为我得到的原始PNG缓冲区...

有没有办法直接设置画布缓冲区?或者有什么方法可以更好地处理流媒体?

我想我可以使用File API将缓冲区写入临时文件,但创建文件会花费很多:(

有什么建议吗?

小智 7

您可以将输入缓冲区转换为Blob,获取它的URL并使用它来绘制到画布上:

function onBinaryMessage(input) {

    var blob = new Blob([input], {type: 'image/png'});
    var url = URL.createObjectURL(blob);
    var img = new Image;

    img.onload = function() {
        var ctx = document.getElementById("canvas").getContext('2d');
        ctx.drawImage(this, 0, 0);
        URL.revokeObjectURL(url);
    }
    img.src = url;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这将是异步的,您需要在onload处理程序内部提供回调机制(在任何情况下,您确实需要在您自己的示例中执行此操作).但是您不必转换为base64等,这是一项相对昂贵的操作.

另请注意,URL.createObjectURL目前是实验性的.