4

我通过以原始 ImageData 格式(RGBA 顺序每像素 4 个字节)发送每一帧来通过 WebSocket 流式传输视频。当我收到客户端上的每一帧(作为)时,我想使用putImageDataArrayBuffer尽可能有效地将这个图像直接绘制到画布上。

这是我目前的解决方案:

// buffer is an ArrayBuffer representing a properly-formatted image
var array = new Uint8ClampedArray(buffer);
var image = new ImageData(array, width, height);
canvas.putImageData(image, 0, 0);

但它比较慢。我关于原因的理论:

  • 数组(大小约为 1MB)被复制三次,一次复制到Uint8ClampedArray,一次复制到ImageData,最后复制到画布中,每帧(每秒 30 次)。

  • new每帧使用两次,这可能是垃圾收集器的问题。

这些理论是否正确,如果正确,我可以使用什么技巧来尽可能快地做到这一点?我愿意接受特定于浏览器的答案。

4

1 回答 1

5

不,您的 ImageDataimage和 TypedArray array共享完全相同的缓冲区buffer

这些只是指针,您的原始缓冲区永远不会“复制”。

var ctx = document.createElement('canvas').getContext('2d');

var buffer = ctx.getImageData(0,0,ctx.canvas.width, ctx.canvas.height).data.buffer;

var array = new Uint8ClampedArray(buffer);

var image = new ImageData(array, ctx.canvas.width, ctx.canvas.height);

console.log(array.buffer === buffer && image.data.buffer === buffer);

对于您的处理时间问题,最好的方法是将视频流直接发送到 videoElement 并使用drawImage.

于 2016-09-21T03:36:19.323 回答