HTML5 Canvas: Change Image Color

11,132

Your recoloring algorithm sets the 4th byte of each RGBA quartet to 255, which discards the alpha channel of the overlay and breaks the anti-aliasing around the edges of the image. Keeping the alpha channel of the original gives you better results:

for(var p = 0, len = data.length; p < len; p+=4) {
    data[p + 0] = rgbColor.r;
    data[p + 1] = rgbColor.g;
    data[p + 2] = rgbColor.b;
}

JSFiddle with the lines commented out

Share:
11,132
Mohit Pandey
Author by

Mohit Pandey

Updated on June 13, 2022

Comments

  • Mohit Pandey
    Mohit Pandey almost 2 years

    I have an image(in greyscale form) of which i want to change the color(user specific). Since its quite difficult to change the color of a greyscale image, i come with an approach.

    Image is divided into two parts.

    1. One is the image with white color.
    2. Second, a semi transparent image with grayscale.

    Now, i place both image on top of each other(with white image on below and greyscale image on top) such that when i change the color of white image, it will be visible to user.

    Problem: This approach works for me, except one issue. When i color the white image, it will pixellete from corners.

    JSFiddle: http://jsfiddle.net/pandey_mohit/BeSwL/

    JSFiddle contains three images for capsules:

    1. Top Capsule Part White Image (for coloring)
    2. Bottom Capsule Part White Image (for coloring)
    3. Semi Transparent Image for 3D effect (using grayscale)

    Select red, green or blue color to see the issue.

    function hexToRgb(color) {
        var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
        color = color.replace(shorthandRegex, function(m, r, g, b) {
            return r + r + g + g + b + b;
        });
    
        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
        } : {
            r: 0,
            g: 0,
            b: 0
        };
    }
    
    function colorImage(imgId,hexaColor) {
        // create hidden canvas (using image dimensions)
        var imgElement = document.getElementById(imgId);
    
        var canvas = document.createElement("canvas");
        canvas.width = imgElement.width;
        canvas.height = imgElement.height;
    
        var ctx = canvas.getContext("2d");
        ctx.drawImage(imgElement,0,0);
    
        var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
    
        var data = imageData.data;
    
        // convert image to grayscale
        var rgbColor = hexToRgb(hexaColor);
    
        for(var p = 0, len = data.length; p < len; p+=4) {
            if(data[p+3] == 0)
               continue;
            data[p + 0] = rgbColor.r;
            data[p + 1] = rgbColor.g;
            data[p + 2] = rgbColor.b;
            data[p + 3] = 255;
        }
        ctx.putImageData(imageData, 0, 0);
    
        // replace image source with canvas data
        imgElement.src = canvas.toDataURL();
    }
    
    // changing color of capsule on select event
    document.getElementById('sel_top').onchange = function(){
        colorImage('img_top', this.value);
    }
    document.getElementById('sel_bottom').onchange = function(){
        colorImage('img_bottom', this.value);
    }