Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
159 views
in Technique[技术] by (71.8m points)

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

Is there a way to change colors of an image much like in Flash/ActionScript with using only HTML5/CSS/JavaScript?

Here's an example in Flash: http://www.kirupa.com/developer/actionscript/color.htm EDIT: This is the process I wish to duplicate.

I'm trying to accomplish something like this (color changing aspect, preserving lighting and shadows): http://www.acura.com/ExteriorColor.aspx?model=TL WITHOUT loading & replacing a new image each time; I want to be able to simply change the color tone (i.e. do a pure HTML5/CSS/JS method). EDIT: This is the result I wish to achieve, not the process.

Basically I want to change the palette/tone of an image, while preserving the other aspects of the image (such as gradient, lighting, etc.). I have gotten close, but not close enough; I've gotten to the point where I use an image mask and composite that over the original image (sort of like a transparent image overlay). Below is some sample code (please note this is just a snippet, so it may or may not work; I am only displaying sample code so you get an idea of what I'm trying to do):

<div id='mask'>
    <canvas id='canvas' width='100' height='100'></canvas>
</div>
<button data-rgba='255,0,0,0.5'>red</button>
<button data-rgba='0,255,0,0.5'>green</button>

<script>
foo = {};
foo.ctx = jQuery('#canvas')[0];
foo.ctx_context = foo.ctx.getContext('2d');
foo.mask = jQuery('#mask')[0];
foo.img = new Image();
foo.img_path = '/path/to/image_mask.png'; // 100px x 100px image

foo.changeColor = function(rgba){
    foo.ctx_context.clearRect(0, 0, 100, 100);
    foo.ctx_context.fillStyle = 'rgba(' + rgba + ')';
    foo.ctx_context.fillRect(0, 0, 100, 100);
    foo.ctx_context.globalCompositeOperation = 'destination-atop';
    foo.ctx_context.drawImage(foo.img, 0, 0);
    foo.ctx_context.css({'background-image': "url(" + foo.ctx.toDataURL("image/png") + ")"});
};

jQuery("button").click(function(){
    foo.changeColor(jQuery(this).attr('data-rgba'));
});
</script>

The major problem with using this approach is that the images look really flat. There's something else missing, or the mask I'm using (which is a solid white irregular shaped image), is the wrong approach.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This function requires the image to be loaded and it has to be from the same domain (due to cross domain policy)

function tintImage(imgElement,tintColor) {
    // create hidden canvas (using image dimensions)
    var canvas = document.createElement("canvas");
    canvas.width = imgElement.offsetWidth;
    canvas.height = imgElement.offsetHeight;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(imgElement,0,0);

    var map = ctx.getImageData(0,0,320,240);
    var imdata = map.data;

    // convert image to grayscale
    var r,g,b,avg;
    for(var p = 0, len = imdata.length; p < len; p+=4) {
        r = imdata[p]
        g = imdata[p+1];
        b = imdata[p+2];
        // alpha channel (p+3) is ignored           

        avg = Math.floor((r+g+b)/3);

        imdata[p] = imdata[p+1] = imdata[p+2] = avg;
    }

    ctx.putImageData(map,0,0);

    // overlay filled rectangle using lighter composition
    ctx.globalCompositeOperation = "lighter";
    ctx.globalAlpha = 0.5;
    ctx.fillStyle=tintColor;
    ctx.fillRect(0,0,canvas.width,canvas.height);

    // replace image source with canvas data
    imgElement.src = canvas.toDataURL();
}

Assuming your markup looks like this:

<img id='myimage' src='image.jpg'/>

You could use it by calling it with the following parameters:

tintImage(
    document.getElementById('myImage'),
    "#550000" // for a redish tint
);

Working example here: http://jsfiddle.net/pHwmL/1/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...