How to crop the png image and remove its unused space using Canvas in flutter?

1,268

Worked source code! Answer by @pskink.

  Future<List<int>> cropRonded(ui.Image image) async {
    var recorder = ui.PictureRecorder();
    var canvas = Canvas(recorder);
    var imageSize = Size(image.width.toDouble(), image.height.toDouble());
    var boundsToCrop = Rect.fromCenter(
        center: imageSize.center(Offset.zero),
        width: imageSize.shortestSide,
        height: imageSize.shortestSide);
    var matrix = Matrix4.translationValues(
            -boundsToCrop.topLeft.dx, -boundsToCrop.topLeft.dy, 0)
        .storage;
    var paint = Paint()
      ..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, matrix);
    var radius = imageSize.shortestSide / 2;
    canvas.drawCircle(Offset(radius, radius), radius, paint);


    ui.Image cropped = await recorder
        .endRecording()
        .toImage(imageSize.shortestSide.toInt(), imageSize.shortestSide.toInt());
    var byteData = await cropped.toByteData(format: ui.ImageByteFormat.png);
    return byteData.buffer.asUint8List();
  }
Share:
1,268
jazzbpn
Author by

jazzbpn

With 6+ years of experience, I have developed many iOS/android applications in different context, professional and oldest passion for computer programming began very early in my life. I've learned the social environment is as important as logic aspects of the developing approach then I appreciate very much to get in touch with positive and eager colleagues that involve me in new and exciting challenges. This is why I still want to get involved in new opportunities to improve my skillness.

Updated on November 20, 2022

Comments

  • jazzbpn
    jazzbpn over 1 year

    This attachment is from the rendered canvas image which is saved locally via canvas. In image I have drawn the square box which I want to render in canvas and save locally without left and right extra spaces. I just want to save the square box and remove that unnecessary space of PNG-image. So, how to do this?

    enter image description here

    widget-source-code:

      return CustomPaint(
        painter: PngImageCropper(image: image),
      );
    

    PngImageCropper-code

      class PngImageCropper extends CustomPainter {
        PngImageCropper({
          this.image,
        });
    
        ui.Image image;
    
        @override
        void paint(Canvas canvas, Size size) {
          _drawCanvas(size, canvas);
          _saveCanvas(size);
        }
    
        Canvas _drawCanvas(Size size, Canvas canvas) {
          final center = Offset(image.width / 2, image.height / 2);
    
          double drawImageWidth = 0;
          double drawImageHeight = 0;
    
          Rect rect =
              Rect.fromCircle(center: center, radius: _getCircularRadius(image));
          Path path = Path()..addOval(rect);
    
          canvas.clipPath(path);
          Paint paint = new Paint();
    
          canvas.drawImage(
            image,
            Offset(drawImageWidth, drawImageHeight),
            paint,
          );
    
          return canvas;
        }
    
        _getCircularRadius(ui.Image image) {
          return image.height > image.width
              ? image.width.toDouble() / 2
              : image.height.toDouble() / 2;
        }
    
        _saveCanvas(Size size) async {
          var pictureRecorder = ui.PictureRecorder();
          var canvas = Canvas(pictureRecorder);
          var paint = Paint();
          paint.isAntiAlias = true;
    
          _drawCanvas(size, canvas);
    
          var pic = pictureRecorder.endRecording();
          ui.Image img = await pic.toImage(image.width, image.height);
          var byteData = await img.toByteData(format: ui.ImageByteFormat.png);
          var buffer = byteData.buffer.asUint8List();
    
          // var response = await get(imgUrl);
          var documentDirectory = await getApplicationDocumentsDirectory();
          File file = File(join(documentDirectory.path,
              '${DateTime.now().toUtc().toIso8601String()}.png'));
          file.writeAsBytesSync(buffer);
    
          print(file.path);
        }
    
        @override
        bool shouldRepaint(CustomPainter oldDelegate) {
          return false;
        }
      }
    
    • pskink
      pskink over 4 years
      what do you need CustomPainter for? you want to save circular image only? without black frame?
    • jazzbpn
      jazzbpn over 4 years
      Cause I have the to some image manipulation and have to render that manipulated image and save it to local storage.
    • jazzbpn
      jazzbpn over 4 years
      Waao! Awesome It works.
    • jazzbpn
      jazzbpn over 4 years
      Hello @pskink Is there any Listener to listen when the CustomPainter paint(..) task is completed? I have to rebuild the widget as soon as the paint(..) task is completed.