Javascript – Convert Image Color without changing its transparent background

canvashtmljavascript

Does anybody have a good solution to change the color of a non-transparent area, with the help of HTML5 or Canvas (or any other HTML5 technology).

I googled a lot and found some solution (with Canvas) which can change the color of an image,like,

How do i tint an image with HTML5 Canvas?

Canvas – Change colors of an image using HTML5/CSS/JS?

But these solution also change the transparent background to the given color (which i don't want).

Stackoverflow image with transparent pixel(background)

Its a stackoverflow png image with transparent background. Now, i want to change image color without affecting its transparent pixels(background), so that i am able to save an image again with the help of canvas toDataURL method with new color.

I am not sure whether is it possible with HTML5 or not. Any help is highly appreciated.

Thanks in Advance.

*******************EDITED*********************

Added new Image of Pill (capsule).

enter image description here

Best Answer

A Demo (see note about this demo below): http://jsfiddle.net/m1erickson/2d7ZN/

enter image description here

You can get an array containing the image's RGBA pixel data using context.getImageData

var imageData=context.getImageData(0,0,canvas.width,canvas.height);

var data=imageData.data;

From there you can read (and optionally change) the color of each pixel.

The rgba array is laid out like this:

// top-left pixel (x:0,y:0)

data[0]   red of pixel#0 (0-255)
data[1]   green of pixel#0 (0-255)
data[2]   blue of pixel#0 (0-255)
data[3]   alpha of pixel#0 (opacity: 0-255)

// next pixel (x:1,y:0)

data[4]   red of pixel#1
data[5]   green of pixel#1
data[6]   blue of pixel#1
data[7]   alpha of pixel#1

You can change the R,G,B or A component of any pixel by changing the data array

For example, this changes the top left pixel to solid red

data[0]=255;   // red
data[1]=0;     // green
data[2]=0;     // blue
data[3]=255;   // alpha (opacity)

About transparency:

The alpha component of each pixel determines that pixel's transparency. If you only want to modify mostly opaque pixels then you can easily ignore all the semi-transparent pixels like this:

// alpha is 0-255
// ignore pixels with alpha < 200 (ignore all pixels that are mostly semi-transparent)

if( data[3]<200 ) { // don't process this pixel }

Finally, you can push your modified pixels back to the canvas with .putImageData

context.putImageData(imageData,0,0);

Note about the Demo

It's difficult to "recolor" an image using the canvas's default RGBA color scheme.

So this demo converts the RGB data to the HSL color scheme. This allows the "color" (hue) to be changed without affecting the other components of the pixel (S=saturation of the color, L=lightness of the color).

After the pixel is recolored, that modified HSL data is converted back to RGBA and saved to the data array.