bariskau
bariskau

Reputation: 347

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>

Upvotes: 2

Views: 2152

Answers (2)

bariskau
bariskau

Reputation: 347

For those who don't use fabric.js, I have a special solution for this question. I briefly explained how it works.

  • It uses 2 canvases instead of one html canvas.
  • One canvas contains image information while the other one stores a mask image with black and white colors. Drawings made with a brush are stored on this canvas.
  • Then the pixels in the mask canvas are shifted 8 bits to the left. The black areas are thus made transparent. With the source-in composite operation, the image is drawn on the canvas where the mask information is written.
  • As a result, the image is masked.

Below is a demo link of the solution I mentioned. There is also github information in the demo, if you want to see the code, you can look at it.

demo

Upvotes: -1

coding-dude.com
coding-dude.com

Reputation: 808

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

Upvotes: 3

Related Questions