Skip to content
Advertisement

Fabric.js create dynamic image mask

I want to mask the original image using alpha mask image. I can do alpha masking on image with the following code. But I want to be able to edit the mask with the brush, how can I do that?

In theory if I paint the mask white it should be opaque, if I paint it black it should be transparent.

The code I tried:

window.onload = function () {
        var img = document.getElementById("mask");
        var canvas = document.getElementById("canvas");
        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) data32[i] = data32[i++] << 8;
        ctx.putImageData(idata, 0, 0);


        ctx.globalCompositeOperation = "source-in";

        const defaultImg = document.getElementById('img');
        ctx.drawImage(defaultImg, 0, 0);

    };
    .container {
            text-align: center;
        }
<div class="container">
    <p>Default Image </p>
    <img id="img" crossorigin="anonymous" src="https://i.ibb.co/FhgZgzN/cat.png">

    <p>Mask </p>
    <img id="mask" crossorigin="anonymous" src="https://i.ibb.co/NswxsLc/cat-mask.png">

    <p>Result </p>:
    <canvas id="canvas"></canvas>
</div>

Advertisement

Answer

You can use FabricJS to enable mask drawing. I’ve done this in the MockoFun graphic designer.

There’s a discussion on Github about this: https://github.com/fabricjs/fabric.js/issues/6465#issuecomment-1127690007

Create a new brush that extends the PencilBrush (https://github.com/fabricjs/fabric.js/blob/master/src/brushes/pencil_brush.class.js)

Add 2 options for this brush:

  • targetMaskFilter – to store the reference to the BlendImage filter
  • mode that is source-over or destination-over to remove/add from the mask image

The idea is to draw on the mask layer using the brush and then combining the mask with the original image using the BlendImage filter.

Here’s a Gist showing my implementation: https://gist.github.com/codingdudecom/ba183221d705a23962fcfcd3cae0c63f

Advertisement