Home > OS >  Flutter cropping around specific object in an image
Flutter cropping around specific object in an image

Time:09-22

There are a couple of cropping plugins for flutter, but they crop only as rectangles, square or oval shapes. I need to crop an specific object(Ex: only an animal of a photo without its background). This is very similar to the 'Lasso Selector Tool or Magnetic Lasso Tool of Photoshop. enter image description here

Is there any such plugin in Flutter? I search in pub.dev, but no luck.

CodePudding user response:

Flutter has a ClipPath() widget that can clip a child with a structured path (like Photoshop path layer->create vector mask, or drawing a path with the lasso tool and cutting out the image). You can have a Container() contain a background image, and clip it with ClipPath().

//in your build()
ClipPath(
  clipper: MyClipperPath(), //you can pass in your own args if you want
  child: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: //your image - AssetImage(), NetworkImage() etc.
        fit: BoxFit.fill, //or whatever BoxFit you want
      )
    )
  )
)

Then outside your widget class

class MyClipperPath extends CustomClipper<Path> {
  MyClipperPath();

  @override
  Path getClip(Size size) {
    //size.height and size.width are the width and height of your child: Container() above

    Path path = Path();
    path.moveTo(0,0);
    path.lineTo(size.width,0);
    path.lineTo(size.width/3,size.height/3);
    path.lineTo(0,size.height);
    path.close();
    
    return path;
  }
}

The above path is an L-like shape. Change the lineTo values and you'll see the clipping path update on screen.

The Path class has a bunch of methods to create lines and curves, including multiple methods for bezier segment types which is what you'd use to copy the way paths or the lasso tool in Photoshop define arbitrary shapes.


Here's a CustomClipper object I'm using in my app. It creates an S-shaped edge on a box.

class TabClipper extends CustomClipper<Path> {
  final double radius;
  const TabClipper([this.radius = 0]);
  @override
  Path getClip(Size size) {
    double _radius = radius;
    if(_radius==0) _radius = size.height * 16 / 57;
    final path = Path();
    path.arcToPoint(Offset(_radius,_radius), radius: Radius.circular(_radius*0.95),rotation: 90.0);
    path.lineTo(_radius, size.height - _radius);
    path.arcToPoint(Offset(_radius*2,size.height), radius: Radius.circular(_radius*0.95),rotation: 90.0, clockwise: false);
    path.lineTo(size.width, size.height);
    path.lineTo(size.width, 0.0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper oldClipper) {return false;}
}
  • Related