Looping through pixels in an image

19,649

Solution 1

It's straightforward.

All the pixel data for a canvas are stored sequentially in an array.

The first pixel's data occupy array elements #0-3 (red=0/green=1/blue=2/alpha=3).

The second pixel's data occupy array elements #4-7 (red=4/green=5/blue=6/alpha=7).

And so on...

You can load that pixel data by using context.getImageData() and enumerating through the array:

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];
}

You can also change those array values and then save the array back to the image using context.putImageData().

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

context.putImageData(imgData, 0, 0);

The image will then change according to the changes you made to its pixel array.

Each pixel contains 4 components red, green, blue, alpha - each of them is number 0-255. The loop starts from top-left to bottom-right.

Solution 2

I recommend you to use an image processing framework in order to focus on the algorithms instead of manipulating arrays of values. Some frameworks:

In the case of MarvinJ, you can simply loop through pixels iterating column and row coordinates. I use the methods getIntComponentX() to access color components.

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);
    }
}

Therefore you don't need to worry about how the pixel data is represented. In order to check if a pixel is white:

// Is white?
if(red >= 250 && blue >= 250 && green >= 250){
    console.log("Pixel at "+x+","+y+" is white");
}

Runnable Example:

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>
Share:
19,649

Related videos on Youtube

user2517142
Author by

user2517142

Updated on June 21, 2022

Comments

  • user2517142
    user2517142 over 1 year

    My project is to input an image into a canvas tag in an HTML page, and then loop through the pixels and RGBA values of the pixels. While looping through the red values,so every fourth value in the pixel, I want to log the position of the pixels that represent a white pixel. Now, I have the image loading down with some code I got from this blog, http://www.phpied.com/photo-canvas-tag-flip/ .

    He has another post in which he gives some code on how to loop through the pixels and log the information I want to log, but I don't understand it, and I don't want to copy his code without knowing what it is I'm doing. So could anybody please either explain the method he's using or perhaps show me another way to do what he's doing? This is the link to the other post http://www.phpied.com/pixel-manipulation-in-canvas/ .

  • markE
    markE about 6 years
    @AlejandroLozdziejski. Top-left to bottom-right. :-)
  • Xeoncross
    Xeoncross about 6 years
  • TaeKwonJoe
    TaeKwonJoe almost 4 years
    Doing this with MarvinJ is very performant. Thank you for this solution!