【问题标题】:HTML Canvas putImageData causing frame overlapHTML Canvas putImageData 导致帧重叠
【发布时间】:2017-10-31 14:30:52
【问题描述】:

我正在尝试从 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);
        };
`

【问题讨论】:

  • 在每一帧之间的画布上绘制一个空白矩形
  • @dandevis ,我尝试像这样插入空白框架。这是正确的吗 ?因为这段代码也没有运气。 var blank = context.createImageData(canvas.height, canvas.width); context.putImageData(blank,0, 0); context.putImageData(Imgdata,0,0);
  • 我的意思是像在画布上画一个矩形

标签: javascript html html5-canvas


【解决方案1】:

我会说原因很可能是由于 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 函数会完全替换像素。如果套接字数据中未定义任何像素,它们将被设置为零并显示为黑色。

【讨论】:

  • 谢谢你们!在调用 putImageData() 之前调用 black fillRect() 就可以了。
猜你喜欢
  • 2011-07-13
  • 2010-11-02
  • 1970-01-01
  • 2017-01-12
  • 2013-11-27
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多