使用单循环或双循环索引像素

时间:2014-07-11 02:58:26

标签: javascript html5 canvas

我看到一些用户索引[Image Data]数组中的一个像素,使用以下两种方法:

for(var i = 0; i < imageData.length; i+=4) {
    data[i] = r;
    data[i+1] = g;
    data[i+2] = b;
    data[i+3] = a;
}

或使用此方法。

for(var x = 0; w < canvas.width; x++) {
  for(var y = 0; h < canvas.height; y++) {
      var index = (x + y*canvas.width)*4;

  }
}

所以,我想知道两者之间有什么区别。另外,如果两者相同,则最快。

2 个答案:

答案 0 :(得分:0)

这两种方法都会产生相同的结果。我假设一旦计算出两个图像中的索引位置相同。唯一改变的是像素被改变的顺序。

对于速度,第二个可能会更慢。首先,这是因为缓存速度,程序可以比连续访问阵列中的位置更快地访问类似阵列位置中的数据。此外,编译器必须执行一些乘法运算和添加才能重新计算索引,而不仅仅是添加。为了在第二个上加快速度,尝试将x和y切换为循环,或者用canvas.width将x乘以canvas.height而不是y。

答案 1 :(得分:0)

这完全取决于您的需求:

•如果需要线性迭代所有像素,只需执行:

var pixelCount=data.length, i=0;
while (pixelCount--) {
    data[i++] = r;
    data[i++] = g;
    data[i++] = b;
    data[i++] = a;
}

•如果迭代所有像素,但需要每个点的(x,y)执行一些计算,请执行以下操作:

var index=0, canvasWidth = canvas.width, canvasHeight = canvas.height ;
for(var y = 0; h < canvasHeight; y++) {
    for(var x = 0; w < canvasWidth ; x++) {        
        data[index++] = /* depends on x, y */;
        data[index++] = /* depends on x, y */;
        data[index++] = /* depends on x, y */;
        data[index++] =  /* depends on x, y */;
    }
 } 

(缓存canvas.width / height以避免循环中的DOM访问尤其重要)。

•如果在数据中迭代一个矩形,那么你就无法避免计算索引,你可以通过使用位移来加快速度:

  var startX = ?? , startY = ???, endX = ???, endY = ??? ;
  var canvasWidth = canvas.width;
  var index=0;
  for(var y = startY; y <= endY; y++) {
      for(var x = startX; x <= endX ; x++) {      
          index = ( y * canvasWidth + x ) << 2 ;   
          data[index] = ... ;
          data[index+1] = ... ;
          data[index+2] = ... ;
          data[index+3] = ... ;
      }
   }