1

我想裁剪一个矩形图像文件并使其成为圆形或正方形或六边形并将其保存为本地图像文件。我有一个位图,我想从这个位图中裁剪一个圆形或六边形区域。圆圈外的所有像素都应该是透明的。我怎样才能做到这一点?

在此处输入图像描述

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

4

3 回答 3

8

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

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

画布屏幕

在此处输入图像描述

将图像画布保存为 png

在此处输入图像描述

完整源代码:

        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;
          }
        }
于 2019-12-22T09:59:45.900 回答
0

您可以使用simple_image_crop包。

在此处查看我对类似问题的回答-

于 2019-12-21T08:45:45.120 回答
-1

使用 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,

)

于 2019-12-21T14:27:14.513 回答