3

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...

nizzle
  • 1,036
  • 2
  • 10
  • 23

2 Answers2

5

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";
}
Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136
0

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>