I am completely new to HTML5 and would like to know if it is possible to display an image (photo) of a car (say a black or white car) and then allow the user to change the color to any hex color.
-
You can use [CSS3 Transitions](http://www.w3.org/TR/css3-transitions/) to achieve that – Incognito Oct 03 '13 at 09:59
-
It's hard (using a photo) do what you want with cool result. You could create a sketch of a car... – BAD_SEED Oct 03 '13 at 10:14
-
[Here's some examples of colourization](http://www.cs.huji.ac.il/~yweiss/Colorization/), there's also a link to the source code they used. If you want to do this in HTML5 you need port that source code to JavaScript, or find an already existing JavaScript implementation. – robertc Oct 03 '13 at 10:20
1 Answers
The HTML5 canvas doesn't provide anything like that out-of-the-box. But you can implement it yourself.
You can get the raw RGBA values of a canvas with context.getImageData(). You can then manipulate these images and put them back with context.putImageData(). This code snippet will take a canvas and then recolor it by calculating the brightness of each pixel (taking average of red, green and blue which is a rather dirty way of doing it - there are better methods, but let's keep it simple for now) and multiply it with the desired red, green and blue intensity to calculate the new red- green and blue value of that pixel.
Here is an example which draws an image to a canvas and then recolors that section of the canvas in purple (RGB 200, 100, 255).
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function() {
var img = new Image();
img.onload = function() {
var context = document.getElementById("canvas").getContext("2d");
// draw an image to the canvas
context.drawImage(img, 0, 0);
// get the pixels from the canvas
var imgData = context.getImageData(0, 0, img.width, img.height);
var pixels = imgData.data;
// recolor the pixels
var RED = 200;
var GREEN = 100;
var BLUE = 255;
for (var i = 0; i < pixels.length; i+=4) {
var brightness = (pixels[i] + pixels[i+1] + pixels[i+2]) / 3;
pixels[i] = brightness * RED / 255;
pixels[i+1] = brightness * GREEN / 255;
pixels[i+2] = brightness * BLUE / 255;
}
// put the recolored pixels back
context.putImageData(imgData, 0, 0);
}
img.src = "image.png";
}
</script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
For simplicity sake this example will recolor the rectangular section of the canvas where the image was drawn. When your image has a transparent background, you likely want to avoid that. To do so create a new canvas element with document.createElement("canvas")
(but don't put it into the document), draw the image to that background canvas, recolor the background canvas, and then draw the background-canvas to the foreground-canvas (drawImage
can use a canvas as a source just like it can use an image). The algorithm above does not touch the alpha-channel (which would be pixels[i+3]
), so any transparent parts of the canvas will stay transparent after recoloring.
Oh, and by the way: This does not work when you load the image from another domain, because when you do that, the canvas will be tainted by cross-origin data and getImageData
doesn't work anymore.

- 67,764
- 9
- 118
- 153
-
Extremely interesting answer! I look forward to playing with this. Can you please explain more about the effects of loading an image from another domain? How do you mean it will be tainted? – Mister Epic Dec 31 '13 at 01:59
-
@ChrisHardie When data from another domain was drawn to a canvas, scripts can no longer read from it. This is a security measure to prevent scripts from reading confidential images from other domains where the user has private access and sending them to the website operator. See http://stackoverflow.com/questions/9972049/cross-origin-data-in-html5-canvas for more information. – Philipp Dec 31 '13 at 02:18
-
@ChrisHardie Example: You are logged into Facebook. I want to look at your private images. You go to my website. My script loads the private images, writes them to a canvas, uses getImageData to read them and sends them to my webserver via XmlHttpRequest. Facebook thinks that the requests for the images come from you, so it will serve them. But the cross-origin restrictions will prevent my script from reading from the canvases where they were drawn, so you can view them, but I can't. – Philipp Dec 31 '13 at 02:30