我正在尝试从websocket读取像素(逐帧)并将其渲染到画布上(灰度)。数据正在正确显示,只是当前帧的像素在前一帧上重叠显示。因此,在几帧之后图片会被污染。
我想在渲染当前帧之前清除前一帧。这样做的正确方法是什么?
我正在使用putImageData()来渲染帧。我在调用putImageData()之前尝试过clearRect()。并且在再次填充之前尝试清除Imgdata(Imgdata.data = [];)数组,但这些都没有用。
` var canvas = document.querySelector("canvas");
var context = canvas.getContext("2d");
var Imgdata = context.createImageData(100,100);
var numPixel = Imgdata.data.length/4;
ws.onmessage = function (event) {
var bytes = new Uint8Array(event.data);
console.log("data: " + numPixel + " bytes: "+ bytes.length);
//Imgdata.data = [];
for (var i = 0; i < numPixel; i++) {
Imgdata.data[(i*4)+Math.round(bytes[i]/85)] = (bytes[i]%85)*3;
Imgdata.data[(i*4)+3] = 255;
Imgdata.data[(i*4)+0] = bytes[i];
Imgdata.data[(i*4)+1] = bytes[i];
Imgdata.data[(i*4)+2] = bytes[i];
Imgdata.data[(i*4)+3] = 255;
}
//context.clearRect(0, 0, canvas.width, canvas.height);
context.putImageData(Imgdata,0,0);
};
`
答案 0 :(得分:0)
我想说原因很可能是因为for循环中的第一行,不知道数据我不知道它做了什么,但id看起来不正确。
// ???
Imgdata.data[(i*4)+Math.round(bytes[i]/85)] = (bytes[i]%85)*3;
如果数据是随机的,那么这将随机设置每个像素的一个颜色通道。
除此之外,我看不出会导致你所描述的任何错误。
我已经重写了代码,仅作为改善性能的建议。
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
const imgdata = context.createImageData(100,100);
const pix = imgdata.data;
pix.fill(255); // set all to 255 To cover the alpha channel
const numPixel = pix.length; // best leave as byte count
ws.onmessage = function (event) {
const inData = event.data;
var inIndex = 0;
var i = 0;
while(i < numPixel){
pix[i ++] = pix[i ++] = pix[i ++] = inData[inIndex ++];
i++;
}
context.putImageData(imgdata,0,0);
};
如果输入数据不完整,那么应该工作事件putImageData函数完全替换像素。如果从套接字数据中未定义任何像素,它们将被设置为零并显示为黑色。