• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

The Coding Couple

Pair programming is a lifetime commitment.

  • Home
  • Categories
    • Arduino
    • JavaScript
    • Python
    • Raspberry Pi
  • About Us
    • Privacy Policy
  • Contact

Counting Pixels in the Browser with the HTML5 Canvas and the ImageData object

January 22, 2020 by Ashley

Count pixels by color in the browser using JavaScript and the HTML 5 Canvas Element

Ashley’s Canvas Pixel Color Counter Web App

I recently wrote a small Python script that accepted an image file and returned the count of pixels per a unique color. The script worked great for my use case (making 8-bit pixel art), and it has saved me a lot of time.

Sample image output of the Python pixel counter

Unfortunately, the command line interface makes it difficult for others to use. I wanted to make the application more accessible for those who aren’t command line savvy nor want to download Python and my script. The best alternative: running the pixel counter in the browser. Thus Canvas Pixel Color Counter was born!

Canvas Pixel Color Counter

Canvas Pixel Color Counter accepts an image and displays the total number of pixels per a color within the image.

I wrote the web app in plain ole JavaScript, CSS and HTML. It was a good exercise to use vanilla JS over a framework, and this project was the first time I needed to write a web worker.

The application was designed with small 16×16 or 32×32 images in mind, but will work for larger images as well. (Be prepared to scroll a lot!)

Canvas’ ImageData Object

The main star of the application is the ImageData object of the canvas. This object facilitates pixel manipulation by storing the canvas’ pixel data.

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');  
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

ImageData has three properties: height, width, and data. data is an Uint8ClampedArray containing the RGBA values of each pixel within the canvas.

Each pixel represents 4 bytes of data within the Uint8ClampedArray. The Red, Green, Blue and Alpha values are one byte each and appear in the array in that order.

To get the RGBA value of each pixel in the image requires a little math:

for(let index = 0; index < imageData.data.length; index += 4) {
    const rgba = [imageData.data[index], 
                  imageData.data[index + 1], 
                  imageData.data[index + 2], 
                 (imageData.data[index + 3] / 255));
    // do something
}    

Each pixel is a clump of 4 elements in the array. In a 2×2 image of 4 pixels, the data array will contain 16 elements. The first 4 elements would represent the pixel in the top right, the next four elements would represent the pixel in the top left, the following 4 elements represent the pixel on the bottom right and finally, the last 4 elements would represent the pixel in the bottom left.

If you wanted the RGBA value of a specific row/column or x/y coordinate in the image you could use the following equation:

const redIndex = y * (width * 4) + x * 4;
const blueIndex = redIndex + 1;
const greenIndex = redIndex + 2;
const alphaIndex = redIndex + 3;
const rgba = [imageData.data[redIndex], 
              imageData.data[blueIndex], 
              imageData.data[greenIndex], 
             (imageData.data[alphaIndex] / 255));

Putting the Pixel Counter to Work

I have used the Canvas Pixel Color Counter for a few projects already. Here’s a sneak peak of one I currently have in progress: 8-Bit Boo from Super Mario Bros. 3!

8-Bit Boo Pixel Art from Super Mario Bros. 3

The code for this project is available for viewing on GitHub!

Let’s be friends!

  • Instagram: @thecodingcouple
  • Twitter: @thecodingcouple
  • GitHub: @thecodingcouple

Related Posts

  • JavaScript’s Null Coalescing Operator | Today I LearnedJavaScript’s Null Coalescing Operator | Today I Learned
  • Trijam #261 Game Jam Diary: One Wrong MoveTrijam #261 Game Jam Diary: One Wrong Move
  • Pokémon Color Picker | A web app built with HTML/CSS + JavaScriptPokémon Color Picker | A web app built with HTML/CSS + JavaScript
  • NESPi Raspberry Pi Case (RetroFlag) Mini ReviewNESPi Raspberry Pi Case (RetroFlag) Mini Review
  • Fractions in Python | Today I LearnedFractions in Python | Today I Learned
  • Avoid using mutable values as default parameter values in Python (Today I Learned)Avoid using mutable values as default parameter values in Python (Today I Learned)

Filed Under: JavaScript, Programming Languages Tagged With: html5, pixels

Previous Post: « Retroflag SuperPi Raspberry Pi Case Review
Next Post: Southeastern Technical Conferences (2020 Edition) »

Primary Sidebar

Social Media

  • GitHub
  • Instagram
  • Twitter
  • YouTube

Recent Posts

  • Pokémon Color Picker | A web app built with HTML/CSS + JavaScript
  • Pokéball Single DIV CSS Drawing | Tutorial
  • Error: [🍍]: “getActivePinia()” was called but there was no active Pinia
  • Trijam #261 Game Jam Diary: One Wrong Move
  • Using WSL on Corporate VPN

Recent Comments

  • Lizzy on Creation Crate Month 2: An Arduino Powered Memory Game
  • Ashley Grenon on Creation Crate Month 2: An Arduino Powered Memory Game
  • Lizzy on Creation Crate Month 2: An Arduino Powered Memory Game
  • kelly on Creation Crate Month 2: An Arduino Powered Memory Game
  • Ashley on Creation Crate Month 3: An Arduino Powered Distance Detector

Follow us on Instagram!

This error message is only visible to WordPress admins

Error: No feed found.

Please go to the Instagram Feed settings page to create a feed.

Categories

  • Arduino
  • Conferences
  • Debugging
  • Game Jams
  • HTML and CSS
  • JavaScript
  • Programming Languages
  • Python
  • Raspberry Pi
  • Today I Learned

Archives

  • May 2024
  • April 2024
  • March 2024
  • May 2022
  • December 2021
  • May 2021
  • March 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • June 2019
  • April 2019
  • September 2017
  • April 2017
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • April 2015
  • January 2015

Tags

adafruit arduino brackets c# code smell codestock coding standards conventions creation crate debugging developer devspace electronics es6 es2015 game development game jam gotcha hackathon hoisting html html5 javascript led naming conventions nintendo phaser pluralsight pokemon programmer python raspberry pi retro retropie scope self improvement single div single div drawing subscription box TIL today I learned troubleshooting vue vuejs windbg

Footer

About Us

We are the Coding Couple.  Two people who met in college and decided they wanted to pair program for the rest of their ...

Read More »

Most Recent Posts

Pokémon Color Picker | A web app built with HTML/CSS + JavaScript

Pokéball Single DIV CSS Drawing | Tutorial

Error: [🍍]: “getActivePinia()” was called but there was no active Pinia

Trijam #261 Game Jam Diary: One Wrong Move

Social Media

  • GitHub
  • Instagram
  • Twitter
  • YouTube

Copyright Notice

© The Coding Couple, 2015 – 2023. Excerpts and links may be used, provided that full and clear credit is given to The Coding Couple with appropriate and specific direction to the original content.

Copyright © 2025 · Foodie Pro Theme by Shay Bocks · Built on the Genesis Framework · Powered by WordPress