我通过以原始ImageData格式发送每个帧(RGBA顺序中每个像素4个字节),通过WebSocket传输视频。当我在客户端上收到每个帧时(作为ArrayBuffer
),我想使用putImageData尽可能高效地将此图像直接绘制到画布上。
这是我目前的解决方案:
// 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
两次,这可能是垃圾收集器的问题。
这些理论是否正确?如果是这样,我可以采用哪些技巧来尽快实现这一目标?我愿意接受特定于浏览器的答案。
答案 0 :(得分:3)
不,您的ImageData image
和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
。