Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating image masks in flutter

Tags:

flutter

Flutter provides several ways for masks based on paths i.e. clip paths. I am trying to figure out a way where one could take an image with transparency layer like example below and use that image to mask another image / view or as a general mask.

My first instinct was to look at CustomPaint class, but I can't figure it out past this initial idea.

enter image description here

like image 924
Ilja Avatar asked Dec 07 '18 20:12

Ilja


People also ask

What is clipBehavior in Flutter?

The clipBehavior property is new and you'll see it a lot in the Material Widgets because of the breaking change discussed a few months ago. With this change Flutter apps are 30% faster, but part of this breaking change is that it disabled the automatic call to saveLayer , and it exposes a clipBehavior property.

How do you use ClipRect Flutter?

First initialize the main app as a stateless widget. Second design the main widget as you desire. Build the Appbar with the scaffold widget. Now use the ClipRect widget inside the body of the scaffold widget and place it in the middle using the center widget.

What is shader mask?

According to official documentation, ShaderMask is a widget that applies a mask generated by a shader to its child.


2 Answers

Flutter has BoxDecoration class that takes in BlendMode enum. By utilising these you can achieve various mask effects using images, for my particular case above dstIn was a solution.

like image 146
Ilja Avatar answered Oct 01 '22 04:10

Ilja


I have posted an answer to my own same problem here, using a custom painter class with a squircle mask and image.

  @override
  void paint(Canvas canvas, Size size) {
    if (image != null && mask != null) {
      var rect = Rect.fromLTRB(0, 0, 200, 200);
      Size outputSize = rect.size;
      Paint paint = new Paint();

      //Mask
      Size maskInputSize = Size(mask.width.toDouble(), mask.height.toDouble());
      final FittedSizes maskFittedSizes =
          applyBoxFit(BoxFit.cover, maskInputSize, outputSize);
      final Size maskSourceSize = maskFittedSizes.source;

      final Rect maskSourceRect = Alignment.center
          .inscribe(maskSourceSize, Offset.zero & maskInputSize);

      canvas.saveLayer(rect, paint);
      canvas.drawImageRect(mask, maskSourceRect, rect, paint);

      //Image
      Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
      final FittedSizes fittedSizes =
          applyBoxFit(BoxFit.cover, inputSize, outputSize);
      final Size sourceSize = fittedSizes.source;
      final Rect sourceRect =
          Alignment.center.inscribe(sourceSize, Offset.zero & inputSize);

      canvas.drawImageRect(
          image, sourceRect, rect, paint..blendMode = BlendMode.srcIn);
      canvas.restore();
    }
  }

Result:

enter image description here

like image 22
Daniel Wilson Avatar answered Oct 01 '22 06:10

Daniel Wilson