javascriptcanvasgetimagedata

Determining the brightness of an image using canvas


I have a function that loops through an image's pixels to determine the average "brightness" of the image as a number between 0 (black) - 255 (white).

The problem is during testing I found that while an image that's entirely black (#000000) will correctly return 0, an image that's entirely white (#FFFFFF) returns a number around 200 instead of 255. Am I missing something?

Here's my function, any help would be appreciated!

function getBrightness(imageSrc, callback) {
  const img = document.createElement("img");
  img.src = imageSrc;
  img.style.display = "none";
  document.body.appendChild(img);
  let colorSum = 0;

    img.onload = function() {
      const canvas = document.createElement("canvas");
      canvas.width = this.width;
      canvas.height = this.height;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(this, 0, 0);

      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      const data = imageData.data;
      let r, g, b, avg;

      for(let x=0, len=data.length; x<len; x+=4) {
        r = data[x];
        g = data[x+1];
        b = data[x+2];
        avg = Math.floor((r+g+b) / 3);
        colorSum += avg;
      }

      const brightness = Math.floor(colorSum / (this.width * this.height));
      callback(brightness);
    }
}

Solution

  • Sorry, but as the snippet below proves, the result for the image you mentioned is 255. Maybe you want to check out what file you were using in the tests ? you're probably using a wrong file...

    function getBrightness(imageSrc, callback) {
      const img = document.createElement("img");
      img.src = imageSrc;
      img.crossOrigin = 'anonymous';
      img.style.display = "none";
      document.body.appendChild(img);
      let colorSum = 0;
    
        img.onload = function() {
          const canvas = document.createElement("canvas");
          canvas.width = this.width;
          canvas.height = this.height;
          const ctx = canvas.getContext("2d");
          ctx.drawImage(this, 0, 0);
    
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          const data = imageData.data;
          let r, g, b, avg;
    
          for(let x=0, len=data.length; x<len; x+=4) {
            r = data[x];
            g = data[x+1];
            b = data[x+2];
            avg = Math.floor((r+g+b) / 3);
            colorSum += avg;
          }
    
          const brightness = Math.floor(colorSum / (this.width * this.height));
          callback(brightness);
        }
    };
    
    
    getBrightness(
        'https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Solid_white.svg/768px-Solid_white.svg.png', 
        (b)=>console.log(b));

    I just included the line img.crossOrigin = 'anonymous'; in order to avoid the cors security message.