在图像中遍历像素

21
我的项目是将图像输入到HTML页面中的canvas标签中,然后循环遍历每个像素及其RGBA值。在循环遍历红色值时,即第四个值,我想记录表示白色像素的像素位置。现在,我已经使用从这篇博客中获得的一些代码加载了图像 http://www.phpied.com/photo-canvas-tag-flip/
他有另一篇文章,其中提供了一些代码来循环遍历像素并记录我想要记录的信息,但我不理解它,也不想在不知道自己在做什么的情况下复制他的代码。因此,请问是否有人可以解释他正在使用的方法,或者向我展示另一种完成相同功能的方式?这是链接到另一篇文章的链接 http://www.phpied.com/pixel-manipulation-in-canvas/
2个回答

59

这很简单。

所有画布的像素数据都按顺序存储在一个数组中。

第一个像素的数据占据数组元素#0-3(红色= 0 /绿色= 1 /蓝色= 2 / alpha = 3)。

第二个像素的数据占据数组元素#4-7(红色= 4 /绿色= 5 /蓝色= 6 / alpha = 7)。

如此类推...

您可以使用context.getImageData()加载该像素数据并通过枚举数组进行访问:

const imgData = context.getImageData(0, 0, canvas.width, canvas.height);
const data = imgData.data;

// enumerate all pixels
// each pixel's r,g,b,a datum are stored in separate sequential array elements

for(let i = 0; i < data.length; i += 4) {
  const red = data[i];
  const green = data[i + 1];
  const blue = data[i + 2];
  const alpha = data[i + 3];
}

您也可以更改那些数组值,然后使用context.putImageData()将数组保存回图像。

// save any altered pixel data back to the context
// the image will reflect any changes you made

context.putImageData(imgData, 0, 0);

图像将根据您对其像素数组所做的更改而发生变化。

每个像素包含4个组件:红色、绿色、蓝色、Alpha - 每个组件的数字范围是0-255。循环从左上角开始,向右向下扫描。


1
@AlejandroLozdziejski。从左上角到右下角。 :-) - markE

4
我建议您使用图像处理框架,以便专注于算法而不是操作值数组。以下是一些框架: 在MarvinJ的情况下,您可以简单地通过像素循环来迭代列和行坐标。我使用方法getIntComponentX()来访问颜色分量。
for(var y=0; y<image.getHeight(); y++){
    for(var x=0; x<image.getWidth(); x++){
        var red = image.getIntComponent0(x,y);
        var green = image.getIntComponent1(x,y);
        var blue = image.getIntComponent2(x,y);
    }
}

因此,您不需要担心像素数据的表示方式。要检查像素是否为白色:
// Is white?
if(red >= 250 && blue >= 250 && green >= 250){
    console.log("Pixel at "+x+","+y+" is white");
}

可运行的示例:

var canvas = document.getElementById("canvas");
image = new MarvinImage();
image.load("https://i.imgur.com/eLZVbQG.png", imageLoaded);

function imageLoaded(){
  
  var whitePixels=0;
  for(var y=0; y<image.getHeight(); y++){
    for(var x=0; x<image.getWidth(); x++){
      var red = image.getIntComponent0(x,y);
      var green = image.getIntComponent1(x,y);
      var blue = image.getIntComponent2(x,y);
      var alpha = image.getAlphaComponent(x,y);
      
      // Is white?
      if(red >= 250 && green >= 250 && blue >= 250 && alpha > 0){
        whitePixels++;
      }
    }
  }
  
  image.draw(canvas);
  
  document.getElementById("result").innerHTML = "white pixels: "+whitePixels;
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>
<canvas id="canvas" width="500" height="344"></canvas>
<div id="result"></div>


1
使用MarvinJ实现这个功能非常高效。感谢您提供的解决方案! - TaeKwonJoe

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