How to re-tint a grayscale image on canvas

前端 未结 3 903
清歌不尽
清歌不尽 2021-01-15 16:27

Is there any quick way to colorize greyscale icon (png image with transparent background) when drawing it on canvas? By colorize I mean turning greyscale icon into lets say

3条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-15 17:02

    Use compositing to re-tint a grayscale image into "greenscale".

    Using compositing is faster than pixel manipulation and as a bonus you won't run afoul of cross-domain security restrictions (which you do if you instead used getImageData).

    1. Create a fully green version of your image.
    2. Draw your grayscale image on the canvas.
    3. Set globalCompositeOperation='color' which causes existing grayscale pixels to be re-tinted ("re-hued") with pixels drawn on top.
    4. Draw your fully green image on the canvas.

    "Color" Compositing will turn the grayscale into greenscale.

    + =

    Note: requires a modern browser with blending capabilities (Edge not IE)

    Example code and a Demo:

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    
    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/koolBW.png";
    function start(){
    
        // create a fully green version of img
        var c=document.createElement('canvas');
        var cctx=c.getContext('2d');
        c.width=img.width;
        c.height=img.height;
        cctx.drawImage(img,0,0);
        cctx.globalCompositeOperation='source-atop';
        cctx.fillStyle='green';
        cctx.fillRect(0,0,img.width,img.height);  
        cctx.globalCompositeOperation='source-over';
    
        // draw the grayscale image onto the canvas
        ctx.drawImage(img,0,0);
    
        // set compositing to color (changes hue with new overwriting colors) 
        ctx.globalCompositeOperation='color';
    
        // draw the fully green img on top of the grayscale image
        // ---- the img is now greenscale ----
        ctx.drawImage(c,0,0);
        
        // Always clean up -- change compositing back to default
        ctx.globalCompositeOperation='source-over';
    }
    body{ background-color:white; }
    #canvas{border:1px solid red; }

提交回复
热议问题