Drawing Pixels With HTML5 Canvas And JavaScript

The HTML5 Canvas provides an API that allows us to draw on the screen. It provides methods to draw basic shapes and to draw images. Sometimes you want to have full control over every pixel that gets drawn on the screen. The API allows for this low-level pixel access by using ImageData objects. This tutorial shows how you can utilize the ImageData object to draw raw pixels on the screen. At the end of the tutorial we create a small demo application that uses the fast pixel drawing techniques to show you what the HTML5 Canvas 2D API is capable of.

Drawing Pixels With HTML5 Canvas And JavaScript

Drawing Pixels With HTML5 Canvas And JavaScript

Click here to go directly to the end of this article and view the demo.

How To Draw Pixels On A Canvas

The HTML5 Canvas 2D API allows us to create an ImageData object. The ImageData object gives us access to the pixel data of an HTML5 Canvas element. After modifying the pixel data of the Image Data object, we can draw the pixels on the Canvas.

Here is how we can create an ImageData object. The dimensions of the image can be specified by using the width and height parameters.

1
var imagedata = context.createImageData(width, height);

The pixels in the ImageData object can be accessed by using the ImageData.data property. The ImageData.data property represents a one-dimensional array of colors. For each of the pixels in the array, there are 4 different colors. Each color is an integer value from 0 to and including 255.

The order of the colors in the array is a repeating sequence of Red, Green, Blue and Alpha values, like this:
Red, Green, Blue, Alpha, Red, Green, Blue, Alpha, …

To calculate the index of a specific pixel at a x and y location, we can use the fact that we know the dimensions of the image and that we know that a single pixel is represented by 4 integer values. The width variable below represents the width of the ImageData object that we created before.

1
var pixelindex = (y * width + x) * 4;

We have the pixel index, so now we can set the actual pixel colors by specifying the red, green, blue and alpha values.

1
2
3
4
imagedata.data[pixelindex] = red;
imagedata.data[pixelindex+1] = green;
imagedata.data[pixelindex+2] = blue;
imagedata.data[pixelindex+3] = alpha;

After we have specified our pixels, we can draw them at a specified x and y location on the canvas using the putImageData function of a canvas rendering context.

1
context.putImageData(imagedata, x, y);

Pixel Drawing Example

If we put everything together, we can create a small demo application that implements drawing raw pixels on the screen. The code below uses ImageData to draw pixels to a canvas with id viewport. It loops over all of the pixels of the canvas and draws a colorful xor pattern.

Here is the HTML5 file index.html:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Pixel Drawing Example - Rembound.com</title>
<script type="text/javascript" src="pixels-example.js"></script>
</head>
<body>
<canvas id="viewport" width="640" height="480"></canvas>
</body>
</html>

Here is the JavaScript file pixels-example.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// The function gets called when the window is fully loaded
window.onload = function() {
    // Get the canvas and context
    var canvas = document.getElementById("viewport"); 
    var context = canvas.getContext("2d");
 
    // Define the image dimensions
    var width = canvas.width;
    var height = canvas.height;
 
    // Create an ImageData object
    var imagedata = context.createImageData(width, height);
 
    // Create the image
    function createImage(offset) {
        // Loop over all of the pixels
        for (var x=0; x<width; x++) {
            for (var y=0; y<height; y++) {
                // Get the pixel index
                var pixelindex = (y * width + x) * 4;
 
                // Generate a xor pattern with some random noise
                var red = ((x+offset) % 256) ^ ((y+offset) % 256);
                var green = ((2*x+offset) % 256) ^ ((2*y+offset) % 256);
                var blue = 50 + Math.floor(Math.random()*100);
 
                // Rotate the colors
                blue = (blue + offset) % 256;
 
                // Set the pixel data
                imagedata.data[pixelindex] = red;     // Red
                imagedata.data[pixelindex+1] = green; // Green
                imagedata.data[pixelindex+2] = blue;  // Blue
                imagedata.data[pixelindex+3] = 255;   // Alpha
            }
        }
    }
 
    // Main loop
    function main(tframe) {
        // Request animation frames
        window.requestAnimationFrame(main);
 
        // Create the image
        createImage(Math.floor(tframe / 10));
 
        // Draw the image data to the canvas
        context.putImageData(imagedata, 0, 0);
    }
 
    // Call the main loop
    main(0);
};

Live Demo

This is a live demo of the code in the previous chapter with some changes to allow a click to play functionality. All of the pixels on the screen are created by the code and at each new frame, the pixels change color.