DEV Community

toolzip
toolzip

Posted on Originally published at toolzip.app

Reading Pixel Data from Images Using Canvas — Histograms and Color Analysis

Reading Pixel Data from Images Using Canvas — Histograms and Color Analysis

The Canvas API gives you direct access to every pixel in an image. Here's how to use that for real analysis: histograms, channel separation, and precise color picking.

Getting Raw Pixel Data

function getImageData(imageFile) {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      resolve(ctx.getImageData(0, 0, img.width, img.height));
    };
    img.src = URL.createObjectURL(imageFile);
  });
}
Enter fullscreen mode Exit fullscreen mode

getImageData() returns a flat Uint8ClampedArray with 4 values per pixel: [R, G, B, A, R, G, B, A, ...].

Building a Histogram

A histogram counts how many pixels have each brightness value (0–255):

function buildHistogram(imageData) {
  const r = new Array(256).fill(0);
  const g = new Array(256).fill(0);
  const b = new Array(256).fill(0);
  const luma = new Array(256).fill(0);

  const data = imageData.data;
  for (let i = 0; i < data.length; i += 4) {
    r[data[i]]++;
    g[data[i + 1]]++;
    b[data[i + 2]]++;
    // Perceptual luminance (BT.601)
    const l = Math.round(0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2]);
    luma[l]++;
  }

  return { r, g, b, luma };
}
Enter fullscreen mode Exit fullscreen mode

The luma formula uses BT.601 weights, which match human perception — green contributes most to perceived brightness.

Channel Separation

To show each color channel as a grayscale image:

function extractChannel(imageData, channel) {
  const result = new ImageData(imageData.width, imageData.height);
  const src = imageData.data;
  const dst = result.data;

  const offset = { r: 0, g: 1, b: 2, a: 3 }[channel];

  for (let i = 0; i < src.length; i += 4) {
    const value = src[i + offset];
    dst[i] = dst[i + 1] = dst[i + 2] = value;
    dst[i + 3] = 255;
  }

  return result;
}
Enter fullscreen mode Exit fullscreen mode

Pixel Color Picker

Get the exact color at a mouse position:

function getPixelColor(canvas, x, y) {
  const ctx = canvas.getContext('2d');
  const pixel = ctx.getImageData(x, y, 1, 1).data;
  const [r, g, b, a] = pixel;

  const hex = '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');

  return { r, g, b, a, hex };
}
Enter fullscreen mode Exit fullscreen mode

Gotcha: The coordinates must be relative to the canvas element, not the page. Use getBoundingClientRect() to convert mouse coordinates.


Analyze your images at toolzip.app/tools/image-inspector.

Top comments (0)