HTML5 Canvas Image Effects: Black & White




The new canvas tag in HTML5 is known for its illustration power. It’s basically an empty element on which you can write and sketch using Javascript. But there’s a hidden power: image manipulation.

In our opinion, this is the most important element that differs from SVG. With canvas you can perform operations on pixel based artworks. You can write a new image pixel by pixel or import an image in the canvas and modify it as you need.

In this article we’ll show you some fundamentals of pixel manipulation in the canvas, and how to use this knowledge to obtain interesting effects. Let’s start from the beginning.

Importing Bitmap Image On Canvas

Importing On Canvas

Let’s take a look at the code to understand how to import an image on the canvas. In our HTML file we have one image with an ID of canvasSource. Then we have our empty canvas element. In the Javascript file we give a context to the canvas and we use the drawImage() function to draw the source image in the canvas. As you can see, there are no visible differences and our canvas looks exactly like the original image.

<!-- HTML Code -->
<img id="canvasSource" src="images/canvas.jpg" alt="Canvas Source" />

<canvas id="area" width="500" height="300">
</canvas>

<!-- Javascript Code -->
<script type="text/javascript">
	window.onload = function() {
	var canvas = document.getElementById("area");
	var context = canvas.getContext("2d");
	var image = document.getElementById("canvasSource");
	context.drawImage(image, 0, 0);
	};
</script>

Now our image is in position, but we need to know more on how to manage pixels.

Managing Pixels

As perfectly described by Opera, pixels in a canvas are represented from left to right, from top to bottom. Every pixel has 4 values: red, green, blue and alpha. It’s easy to understand the power of this principle: you can work on every single pixel and change the values. It’s like editing an image by hand, instead of using a desktop application.

So, looping trough the pixels array, we’re going to get an interesting black and white effect.

Black & White Effect

Black and White Effect

There’s our black and white effect. Let’s start from the beginning of our code because it’s a little bit complex. Using the function getImageData() we store in a variable imgd our image and we’ll be able to access every single pixel by storing the data array in the pix variable. Then we use a for statement to loop through each pixel, and through each value of a single pixel. As described before, every pixel has four values: red, green, blue and alpha. So, pix[i] is red, pix[i+1] is green, pix[i+2] is blue and pix[i+3] is the alpha channel.

<script type="text/javascript">
	var imgd = context.getImageData(0, 0, 500, 300);
	var pix = imgd.data;
	for (var i = 0, n = pix.length; i < n; i += 4) {
	var grayscale = pix[i  ] * .3 + pix[i+1] * .59 + pix[i+2] * .11;
	pix[i  ] = grayscale; 	// red
	pix[i+1] = grayscale; 	// green
	pix[i+2] = grayscale; 	// blue
	// alpha
	}
	context.putImageData(imgd, 0, 0);
</script>

So, what can we use to make an image black and white? The luminance. The luminance is how much a color is luminous to the human eye and it’s used to measure the clipping white in video editing systems, for example. In video editing system a white color that “break” the screen is a white that is too white to be represented on a common TV.

This is important because by calculating the average number between red, green and blue values we could obtain a value for every pixel that represent a static mathematical representation of the color luminance.

But there’s a problem, an human eye see colors dynamically. For example, if we take similar shades of blue and green, our eyes will detect the green color more luminous than the blue. In our algorithm we could use the static average formula, but our image will be too flat, and we’ll lose a lot of color depth.

So, let’s introduce the luminance formula: red x 0.3 + green x 0.59 + blue x 0.11.

This formula calculates the luminance of a color as it’s perceived by the human eye, so the green channel has more importance that the red and the blue. In our Javascript code we calculate for every pixel the grayscale number, by using exactly this formula. Then we assign this value to the red, green and blue channels of our pixel. Buy doing this for every pixel we are able to get a black and white version of our original image. There are obviously other more complex methods to calculate the correct grayscale value, but they could be too heavy to be used in an HTML5 canvas element, and we can say that for an everyday use, the luminance algorithm is good.

Conclusion.

As you can see, HTML5 canvas is a great alternative to static bitmaps. You’ll be able to add a black and white effect on the fly in Javascript, instead of relying on CSS sprites and effects can be refreshed if you change the original image.

Has anyone used this technique before? What do you think? See you in the comment section ;)





About the author:

Marco Lisci (Web Design/Dev) and Luisa Scarlata (Creative/Copywriter) design and develop for the web, have creative ideas and write award-winning copy. Visit their website at Bad Shark Communications.

Comments:

Scroll back to the top