如何在 flutter 中使用 Canvas 裁剪 png 图像并删除其未使用的 space?

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

此附件来自渲染的 canvas 图像,该图像通过 canvas 在本地保存。在图像中,我绘制了要在 canvas 中渲染的方框,并在本地 保存,没有左右额外的 spaces。我只想保存方框并删除不必要的 space PNG 图像。那么,如何做到这一点?

小部件源代码:

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

PngImageCropper-代码

  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 的回答。

  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();
  }