如何在Flutter中从画布上裁剪圆形(或正方形或六边形)区域

时间:2019-12-21 07:43:34

标签: image-processing flutter flutter-layout flutter-test flutter-canvas

我要裁剪矩形的图像文件,并将其制成圆形,正方形或六边形,然后将其另存为本地图像文件。我有一个位图,我想从该位图裁剪圆形或六边形区域。圆外的所有像素均应透明。我该怎么办?

enter image description here

我在android平台上发现了类似的问题。 但是找不到能真正帮助或指导我实现目标的好的资源。请与我分享实现这一目标的想法。

3 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

使用Clipper裁剪图像 使用ClipRRect,ClipOval,还可以使用自定义Clipper将自定义形状呈现给图像 检查此链接https://www.woolha.com/tutorials/flutter-using-clipper-examples

new ClipRRect(
borderRadius: new BorderRadius.circular(8.0),
child: your image child,

答案 2 :(得分:0)

这些简单的步骤可获得所需的结果。

  1. 创建 PictureRecorder
  2. 使用 PictureRecorder 创建画布
  3. 使用 canvas.drawCircle()在画布中绘制圆。
  4. 在PictureRecorder上调用 endRecording()以获得图片。
  5. 在图片上调用 toImage()
  6. 将图像转换为 toByteData()
  7. 使用 getApplicationDocumentsDirectory()
  8. 本地保存图像

画布屏幕

enter image description here

将图像画布另存为png

enter image description here

完整源代码:

        import 'dart:io';

        import 'package:flutter/material.dart';
        import 'dart:ui' as ui;
        import 'package:flutter/services.dart' show rootBundle;
        import 'dart:async';
        import 'dart:typed_data';
        import 'dart:math' as math;
        import 'package:path/path.dart';
        import 'package:path_provider/path_provider.dart';

        class CustomImageCanvas extends StatefulWidget {
          CustomImageCanvas({Key key, this.title}) : super(key: key);

          final String title;

          @override
          _CustomImageCanvasState createState() => _CustomImageCanvasState();
        }

        class _CustomImageCanvasState extends State<CustomImageCanvas> {
          ui.Image image;
          bool isImageloaded = false;
          void initState() {
            super.initState();
            init();
          }

          Future<Null> init() async {
            final ByteData data = await rootBundle.load('assets/image.jpeg');
            image = await loadImage(Uint8List.view(data.buffer));
          }

          Future<ui.Image> loadImage(List<int> img) async {
            final Completer<ui.Image> completer = Completer();
            ui.decodeImageFromList(img, (ui.Image img) {
              setState(() {
                isImageloaded = true;
              });
              return completer.complete(img);
            });
            return completer.future;
          }

          Widget _buildImage() {
            if (this.isImageloaded) {
              return CustomPaint(
                painter: PngImagePainter(image: image),
              );
            } else {
              return Center(child: Text('loading'));
            }
          }

          @override
          Widget build(BuildContext context) {
            return Scaffold(
                appBar: AppBar(
                  title: Text(widget.title),
                ),
                body: Container(
                  child: _buildImage(),
                ));
          }
        }

        class PngImagePainter extends CustomPainter {
          PngImagePainter({
            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(150, 50);
            final radius = math.min(size.width, size.height) / 8;

            // The circle should be paint before or it will be hidden by the path
            Paint paintCircle = Paint()..color = Colors.black;
            Paint paintBorder = Paint()
              ..color = Colors.white
              ..strokeWidth = size.width / 36
              ..style = PaintingStyle.stroke;
            canvas.drawCircle(center, radius, paintCircle);
            canvas.drawCircle(center, radius, paintBorder);

            double drawImageWidth = 0;
            var drawImageHeight = -size.height * 0.8;

            Path path = Path()
              ..addOval(Rect.fromLTWH(drawImageWidth, drawImageHeight,
                  image.width.toDouble(), image.height.toDouble()));

            canvas.clipPath(path);

            canvas.drawImage(image, Offset(drawImageWidth, drawImageHeight), Paint());
            return canvas;
          }

          _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;
          }
        }