2014-09-03 83 views
0

我有一个非常简单的循环,以平铺的方式在画布中多次绘制一幅8像素×8像的图像。目前它每个循环绘制7500个图像。这个画布drawImage()测试的性能可以提高吗?

See the jsfiddle.

var img = new Image(); 
img.src = 'http://i.imgur.com/3dzaMlv.png'; 

var W = 8; 
var H = 8; 
var R = 800/W; 
var C = 600/H 

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

var fps = document.getElementById('fps'); 
var timePrev = new Date().getTime(); 
var fpsInterval = 30; 
var i = 0; 

window.setInterval(function() { 

    ctx.clearRect(0, 0, 800, 600); 

    for (var r=0 ; r<R ; r++) { 
     for (var c=0 ; c<C ; c++) { 
      ctx.drawImage(img, r*W, c*H); 
     } 
    } 

    // fps 
    if (i % fpsInterval == 0) { 
     var timeNow = new Date().getTime(); 
     var spf = (timeNow - timePrev)/fpsInterval/1000; 
     fps.innerHTML = (1/spf).toFixed(2); 
     timePrev = timeNow; 
    } 
    i++; 

}, 1000/60); 

在我I7-2700K(3.5GHz的)处理器和ATI Radeon HD7970,我得到以下帧率:

  • 的Chrome 36.0.1985.143 L:〜40 FPS
  • Firefox 30.0:〜55 FPS
  • IE 11.0.9600.17239:〜35 FPS

有没有办法在这里提高FPS性能,假设我的确需要利用每个更新这么多砖?

编辑:为了澄清,我要求他们被绘制为每个更新单独的瓷砖。因此,将它们全部渲染到屏幕外都不起作用。我对于似乎表现良好的drawImage()调用的数量感到失望。

+1

你应该知道你不在opic to SO去http://codereview.stackexchange.com/ – InferOn 2014-09-03 05:35:45

+0

谢谢wintermute。 [我交叉在那里](http://codereview.stackexchange.com/questions/61825/can-the-performance-of-this-canvas-drawimage-test-be-improved) – 2014-09-03 08:52:55

+1

其实,绘图到关闭屏幕画布正是我所要做的。将每个图块绘制到屏幕外,然后将整个画布喷射到可见的画布上。在这台机器上(i7-3537U-intel hd4000),性能从〜22fps变为〜25fps。不是量子的变化,而是3条额外的代码的成本增加了10%+。另外,除非你的瓷砖有透明区域,否则你不需要'clearRect'调用。 1号线。克隆现有的画布元素。 2号线。获取克隆的ctx,(将代码更改为将图块绘制到副本),第4行。将图像从副本绘制到屏幕画布上。 – enhzflep 2014-09-03 12:14:41

回答

0

enter image description here

这里有一种方法用少得多的drawImage的:

// make a template column 
for(var y=0;y<ch;y+=ih){ 
    ctx.drawImage(img,0,y); 
} 

// flood-fill with the template column 
for(var x=iw;x<cw;x+=iw){ 
    ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch); 
} 

演示:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="http://i.imgur.com/3dzaMlv.png"; 
 
function start(){ 
 

 
    var iw=img.width; 
 
    var ih=img.height; 
 

 
    // make a template column 
 
    for(var y=0;y<ch;y+=ih){ 
 
    ctx.drawImage(img,0,y); 
 
    } 
 

 
    // flood-fill with the template column 
 
    for(var x=iw;x<cw;x+=iw){ 
 
    ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch); 
 
    } 
 

 
}
body{ background-color: ivory; padding:10px; } 
 
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>