Cherry
Cherry

Reputation: 719

Add Rectangle overlay in a camera application and Crop the portrait image in flutter

In my application, I have to capture National Id(same size as a credit card) and have to pass the image to the backend. I have tried the below code to display a rectangle overlay in a camera application:

    return Container(
      height: MediaQuery.of(context).size.height,
      child: Stack(
        children: <Widget>[
          CustomPaint(
            foregroundPainter: Paint(),
            child: CameraPreview(controller),
          ),
          ClipPath(
            clipper: Clip(),
            child: CameraPreview(controller)),
        ],
      ),
    );

   }

class Paint extends CustomPainter{
  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawColor(Colors.grey.withOpacity(0.8), BlendMode.dstOut);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}
class Clip extends CustomClipper<Path>{
  @override
  getClip(Size size) {
    print(size);
    Path path = Path()
    ..addRRect(RRect.fromRectAndRadius(Rect.fromLTWH(10, size.height/2-120, size.width-20, 260), Radius.circular(26)));
    return path;
  }

  @override
  bool shouldReclip(oldClipper) {
    // TODO: implement shouldReclip
    return true;
  }

Now I am able to display the overlay(PFB screenshot).

enter image description here

Then I am navigating the next screen... bypassing the image path

Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => CropImageScreen(imagePath: path),
        ),
      );

Here I am trying to crop the image. But the image height and widths are not correct. Normally in portrait mode height should be more and width should be less.

But I am getting height: 720, width: 1280.

    ImageProperties properties =
        await FlutterNativeImage.getImageProperties(imagePath);
    final height = properties.height;
    final width = properties.width;

    print("1. height is: $height");
    print("2. Width is: $width");

    // I have used some static values to crop the image
    File croppedFile = await FlutterNativeImage.cropImage(
        imagePath, 250, 40, properties.width - 500, 640);

    final originalFile = croppedFile;
    List<int> imageBytes = await originalFile.readAsBytes();

    final originalImage = img.decodeImage(imageBytes);

But my question here is how to use dynamic values to crop the image. The static values I entered above may work for my Samsung device. But these values will not work for other devices.

Any other good solution to crop the image which is there in Rectangle overlay?

Note: I have used 'package:camera/camera.dart' library.

Upvotes: 10

Views: 6818

Answers (1)

Omatt
Omatt

Reputation: 10463

If you've yet to use any plugins for cropping, you can use image_cropper. With this, you can use any of the preset crop aspect ratios or create a custom, and set maxWidth and maxHeight depending on the device's screen size. To fetch the device's height and width, you can either use LayoutBuilder

LayoutBuilder(builder: (context, constraints) {
  debugPrint('Max height: ${constraints.maxHeight}, max width: ${constraints.maxWidth}');
  return Widget(); 
}),

...or MediaQuery.

@override
Widget build(BuildContext context) {
  var screenSize = MediaQuery.of(context).size ;
  debugPrint(`Height: ${screenSize.height}, Width: ${screenSize.width}`);
}

Upvotes: 1

Related Questions