skip to Main Content

I’m trying to apply a mask as it works in Photoshop. Black is transparent, white is visible. However, the composite modes don’t allow for this, I think.

I can only find modes where it uses the alpha channel, but I’d like to use a jpg for smaller filesize…

2

Answers


  1. Use getImageData and putImageData to access raw pixel data

    You need to manually move the pixels.

    To do this load the image, put it onto a canvas, get the canvas pixels. Convert to greyscale and move to alpha. THen put the pixels back onto the canvas.

    var mask;
    var image = new Image;
    image.src = "image name.jpg";
    image.onload = function(){
        var canvas = document.createElement("canvas");
        canvas.width = this.width;
        canvas.height = this.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(this,0,0);
        var data = ctx.getImageData(0,0,this.width,this.height);
        var i = 0;
        while(i < data.data.length){
            var rgb = data.data[i++] + data.data[i++] + data.data[i++];
            data.data[i ++]  = rgb / 3;
        }
        ctx.putImageData(data,0,0);
        mask = canvas;
    }
    

    Once loaded mask is a copy of the image with the alpha channel contains the mean of the RGB channels.

    To use it

    // ctx is the canvas context you want to draw to with the mask
    
    if(mask){
         ctx.globalCompositeOperation = "destination-out";
         ctx.drawImage(mask,0,0);
         ctx.globalCompositeOperation = "source-over";
    }
    
    Login or Signup to reply.
  2. I tried to run your code, but unfortunately it didn’t work as expected.

    I would also like this solution. Could anyone fix it?

    window.onload = function() {
    
      var img = document.getElementById("img");
      var canvas = document.getElementById("c");
      var ctx = canvas.getContext("2d");
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;
      ctx.drawImage(img, 0, 0);
    
      var idata = ctx.getImageData(0, 0, canvas.width, canvas.height);
      var data32 = new Uint32Array(idata.data.buffer);
      var i = 0, len = data32.length;
      
      while(i < len) {
            var rgb = idata.data[i++] + idata.data[i++] + idata.data[i++];
        idata.data[i ++]  = rgb / 3;
      }
      ctx.putImageData(idata, 0, 0)
        
    }
    <img id="img" crossorigin="anonymous" src="https://i.imgur.com/QRGYuWg.png"> ► 
    <canvas id="c"></canvas>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search