优化HTML5画布中像素设置的设置

4

HTML5 Canvas没有明确设置单个像素的方法。

目前我知道的解决方法是:

  • 使用getImageDataputImageData,但由于putImageData的性能较低,因此效率在动画中太低。

  • 使用重型对象如rectputImageData来绘制单个像素,但当需要绘制大量像素时,性能似乎更差。

我看到drawImage函数比putImageData快得多,确实,如果我们用drawImage(new Image(w,h))替换putImageData,它真的很快。 然而,我不知道任何可以快速设置像素的图像作为drawImage参数的解决方案。

这里是一个缓慢的代码示例

HTML:

<canvas id="graph1" width="1900" height="1000"></canvas>

Javascript:

    var canvas=document.getElementById("graph1"),
        ctx=canvas.getContext("2d"),
        imageData,
        data,
        w=canvas.width,
        loop=0,
        t=Date.now();

    window.requestAnimFrame = (function(callback) {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
        function(callback) {
          window.setTimeout(callback, 1000 / 60);
        };
      })();


    function animate() {
        imageData=ctx.createImageData(w, canvas.height);
        data=imageData.data;
        for(i=0;i<30000;i++) { // Loop fast enough
            x=Math.round(w*Math.random());
            y=Math.round(canvas.height*Math.random());   
            data[((w * y) + x) * 4]=255;
            data[((w * y) + x) * 4+1]=0;
            data[((w * y) + x) * 4+2]=0;
            data[((w * y) + x) * 4+3]=255;
        }
        ctx.putImageData(imageData, 0, 0); //Slow
        //ctx.drawImage(new Image(canvas.width, canvas.height),0,0);// Would be about 4x faster even if ImageData would be also blank

        requestAnimFrame(function() {
                loop++;
                if(loop<100)
                    animate();
                else
                    alert('finish:'+(Date.now()-t));
            });
    }
    animate();

如果有人能提供改善性能的技巧。


你尝试过使用 fillRect(x,y,1,1)来放置像素吗? - GameAlchemist
浏览器可能已经发展了,自我写下这条消息以来,但在当时我测试使用矩形对象时,它比任何解决方案都要糟糕。 - Hentold
1个回答

0

putImageData 是您想要使用的(如果您计划使用 HTML5 画布)。 它和 drawImage 一样快。

如果 drawImageputImageData 方法都有类似的图像需要重新绘制,它们最终的速度是相同的。 您正在比较完全随机像素的重绘速度,与不断重复的空白重绘速度。 如果您需要证明这一点,我可以做一个示例。


我完全不确定。您可以查看http://jsperf.com/buffering。`drawImage`比`putImageData`快大约100倍。在我的示例中,将行`ctx.putImageData(...)`替换为行`ctx.drawImage(...)`,您会发现即使对于空白图像(在此示例中仅快4倍,但足以提高动画的流畅性),脚本也更快。顺便说一句,浏览器优化了`drawImage`而不是`putImageData`,这确实非常奇怪。 - Hentold
http://jsfiddle.net/DEw3b/1/ 很有趣的是,这在我的一台电脑上是相等的,但在另一台电脑上不是。无论如何,你不能用draw绘制单个像素。因此,这不是很重要。 - Daniel Moses

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接