SpyreStudios

Web Design and Development Magazine

  • Design
  • Showcase
  • Inspirational
  • Tutorials
  • CSS
  • Resources
  • Tools
  • UX
  • More
    • Mobile
    • Usability
    • HTML5
    • Business
    • Freebies
    • Giveaway
    • About SpyreStudios
    • Advertise On SpyreStudios
    • Get In Touch With Us

HTML5 Canvas Image Effects: Black & White

August 23, 2010 by Marco Lisci 20 Comments

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]
<!– 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>
[/html]

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.

[html]
<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>
[/html]

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 ;)

Filed Under: Design, HTML5, Tutorial

Comments

  1. kevinsturf says

    August 23, 2010 at 10:50 pm

    interesting post wit some nice tips

  2. KK says

    August 24, 2010 at 1:25 am

    Nice post…

  3. Rory says

    August 24, 2010 at 8:34 am

    Pretty sweet tip, nice one!

  4. Patrick DeVivo says

    August 24, 2010 at 12:16 pm

    Very cool Marco! I’d love to see some live samples/demos to play around with color manipulation. I’m not sure about browser support so far, but the canvas element seems very powerful!

  5. Liam says

    August 25, 2010 at 10:42 am

    I’ve used grayscale.js (which uses this technique) on the everton fc intranet to flip between grayscale versions of team crests on click.

  6. ZipQuote says

    August 25, 2010 at 1:48 pm

    Beautiful work & great info.
    Thanks!

  7. Arslan says

    August 25, 2010 at 2:15 pm

    great info

  8. Anna says

    August 27, 2010 at 1:58 am

    Getting into HTML 5, this is pretty interesting. Your posts are very easy to follow. Good job!

  9. SiewShuen says

    August 29, 2010 at 11:08 pm

    Thanks for sharing. Haven’t got to touch on HTML5 yet. Gonna try this out soon. Thanks for taking time to do this :)

  10. kevin says

    August 31, 2010 at 12:14 am

    Sounds great but i couldnt manage to get it working. Tested with Chrome. Has anyone succeded ?

  11. Andrea says

    September 10, 2010 at 6:44 am

    This reminds me when we used to play with pixels in the ’90s (Amiga and PC). I worked on a formula to convert HSV to RGB using the same basics.
    At least we are now using faster hardware.

  12. William Xue says

    September 11, 2010 at 11:28 pm

    Awesome tips. Just love to see how much you can do with HTML5!

  13. Pete G says

    September 12, 2010 at 6:34 pm

    Interesting article, thanks!

    I’ve just finished using something similar on my site – http://petegoodman.com/labs/konami-code/

  14. Vikrant says

    September 16, 2010 at 3:40 pm

    Hi, I would like to know if one can import an image from the desktop to the canvas instead of importing it from a server? I have a website http://www.drawmics.com for which I want to implement this functionality using canvas or svg.

    Thanks
    Vikrant

  15. ramandeep singh says

    October 9, 2010 at 6:15 pm

    Hi I am working on HTML5 canvas tag, I used the getImageData in my example in firefox to change the color of image to grayscale…. but it shows error ….. can any body tell me how to over come this??

    ERROR IS:
    Error: uncaught exception: [Exception… “Security error” code: “1000” nsresult: “0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)” location: “http://www.google.com/extern_js/f/CgJlbiswRTgBLCswWjgALCswDjgBLCswFzgHLCswJzgELCswPDgALCswUTgALCswWTgOLCswCjh_QC8sKzAWOB0sKzAZOCAsKzAhOD9AASwrMCU4z4gBLCswKjgLLCswKzgRLCswNTgELCswQDgTLCswQTgFLCswTjgGLCswVDgBLCswYzgALCswHThXLCswXDgXLCswGDgFLCswJjgOLIACGZACG/Veq5STkSvqE.js Line: 109”]

  16. zendrej says

    February 8, 2011 at 6:59 am

    Has anyone tried to change the image width and height without affecting the clarity of the image.. Please help !

Leave a Reply

Your email address will not be published. Required fields are marked *

Please prove you're human *

Recent Posts

  • 31 Fresh Design Elements for Spring and Easter
  • 10 Templates for Music Concert Flyers
  • How to Build a Web Scraper Using Node.js
  • Best PHP Books, Courses and Tutorials in 2022
  • How to Get Your First Web Design Client

Archives

  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • July 2015
  • June 2015
  • May 2015
  • April 2015
  • March 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • September 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • May 2008
  • April 2008

Categories

  • Accessibility
  • Android
  • Apps
  • Art
  • Article
  • Blogging
  • Books
  • Bootstrap
  • Business
  • CSS
  • Design
  • Development
  • Ecommerce
  • Fireworks
  • Flash
  • Freebies
  • Freelance
  • General
  • Giveaway
  • Graphic Design
  • HTML5
  • Icons
  • Illustrator
  • InDesign
  • Infographics
  • Inspirational
  • Interview
  • Jobs
  • jQuery
  • Learning
  • Logos
  • Matrix
  • Minimalism
  • Mobile
  • Motion Graphics
  • Music
  • News
  • Photoshop
  • PHP
  • Promoted
  • Rails
  • Resources
  • Showcase
  • Tools
  • Tutorial
  • Twitter
  • Typography
  • Uncategorized
  • Usability
  • UX
  • Wallpapers
  • Wireframing
  • WordPress
  • Work

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

SpyreStudios © 2022