Flutter图片编辑插件flutter_image_editor_plugin的使用

Flutter图片编辑插件flutter_image_editor_plugin的使用

flutter_image_editor_plugin 简介

flutter_image_editor_plugin 是一个用于在 Flutter 应用中实现图片编辑功能的插件。它允许用户在图片上进行绘制、擦除等操作,并且支持将编辑后的图片导出。


使用步骤

1. 添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter_image_editor_plugin: ^版本号

然后运行 flutter pub get 安装依赖。


2. 创建基本布局

我们通过一个简单的例子展示如何使用 flutter_image_editor_plugin 插件来实现在图片上的绘制功能。

示例代码

import 'package:flutter/material.dart';
import 'package:flutter_image_editor_plugin/flutter_image_editor_plugin.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  /// 绘制线条集合
  final List<DrawLine> drawLines = [];

  /// 绘制区域的 Key
  final boundaryKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: _getAppbar(),
        body: _getBody(),
      ),
    );
  }

  PreferredSizeWidget _getAppbar() {
    return AppBar(
      title: const Text('Flutter Image Editor Plugin 示例'),
    );
  }

  Widget _getBody() {
    return GestureDetector(
      onPanStart: onPanStart, // 开始绘制
      onPanUpdate: onPanUpdate, // 更新绘制
      onPanEnd: onPanEnd, // 结束绘制
      child: RepaintBoundary(
        key: boundaryKey, // 绘制区域的唯一标识
        child: CustomPaint(
          foregroundPainter: ImageEditPainter(drawLines: drawLines), // 自定义画笔
          child: Image.asset('assets/test_image.jpg'), // 需要编辑的图片
        ),
      ),
    );
  }

  /// 开始绘制
  void onPanStart(DragStartDetails details) {
    final box = boundaryKey.currentContext!.findRenderObject() as RenderBox;
    final point = box.globalToLocal(details.globalPosition);

    // 自定义绘制样式
    final paint = Paint()
      ..color = Colors.red
      ..strokeWidth = 10;

    setState(() {
      drawLines.add(DrawLine(path: Path(), drawPoint: [point], paint: paint));
    });
  }

  /// 更新绘制
  void onPanUpdate(DragUpdateDetails details) {
    final box = boundaryKey.currentContext!.findRenderObject() as RenderBox;
    final point = box.globalToLocal(details.globalPosition);

    setState(() {
      drawLines.last.drawPoint!.add(point); // 将新绘制的点加入到最后一条线中
    });
  }

  /// 结束绘制
  void onPanEnd(DragEndDetails details) {
    setState(() {}); // 更新状态以触发重绘
  }
}

3. 自定义画笔逻辑

CustomPaintforegroundPainter 属性允许我们自定义绘制逻辑。在上面的代码中,我们通过 ImageEditPainter 来处理绘制线条的逻辑。

ImageEditPainter 示例代码

import 'package:flutter/painting.dart';

class ImageEditPainter extends CustomPainter {
  final List<DrawLine> drawLines;

  ImageEditPainter({required this.drawLines});

  @override
  void paint(Canvas canvas, Size size) {
    for (var line in drawLines) {
      if (line.drawPoint == null || line.drawPoint!.isEmpty) continue;

      canvas.drawPath(line.path, line.paint);

      // 动态更新路径
      if (line.drawPoint != null && line.drawPoint!.length > 1) {
        var path = Path();
        path.moveTo(line.drawPoint![0].dx, line.drawPoint![0].dy);
        for (int i = 1; i < line.drawPoint!.length; i++) {
          path.lineTo(line.drawPoint![i].dx, line.drawPoint![i].dy);
        }
        line.path = path;
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

// 绘制线条的类
class DrawLine {
  Path path;
  List<Offset>? drawPoint;
  Paint paint;

  DrawLine({
    required this.path,
    required this.paint,
    this.drawPoint,
  });
}

4. 导出编辑后的图片

完成编辑后,可以将编辑后的图片导出为文件。可以通过 RepaintBoundary 获取绘制区域的截图并保存。

Future<void> saveImage() async {
  RenderRepaintBoundary boundary =
      boundaryKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
  ui.Image image = await boundary.toImage(pixelRatio: 3.0);
  ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
  if (byteData != null) {
    final file = File('path_to_save/image.png');
    await file.writeAsBytes(byteData.buffer.asUint8List());
  }
}

更多关于Flutter图片编辑插件flutter_image_editor_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片编辑插件flutter_image_editor_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_image_editor_plugin 是一个用于在 Flutter 应用中编辑图片的插件。它提供了裁剪、旋转、缩放、添加文本、添加贴纸等功能。以下是如何使用 flutter_image_editor_plugin 的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 flutter_image_editor_plugin 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_image_editor_plugin: ^latest_version

然后运行 flutter pub get 来安装依赖。

2. 导入插件

在你的 Dart 文件中导入插件:

import 'package:flutter_image_editor_plugin/flutter_image_editor_plugin.dart';

3. 使用插件

以下是一些常见的使用场景:

3.1 裁剪图片

Future<void> cropImage() async {
  final String imagePath = 'path_to_your_image.jpg';
  final Rect cropRect = Rect.fromLTWH(50, 50, 200, 200); // 定义裁剪区域

  final String croppedImagePath = await FlutterImageEditorPlugin.cropImage(
    imagePath: imagePath,
    cropRect: cropRect,
  );

  print('Cropped image saved at: $croppedImagePath');
}

3.2 旋转图片

Future<void> rotateImage() async {
  final String imagePath = 'path_to_your_image.jpg';
  final int degrees = 90; // 旋转角度

  final String rotatedImagePath = await FlutterImageEditorPlugin.rotateImage(
    imagePath: imagePath,
    degrees: degrees,
  );

  print('Rotated image saved at: $rotatedImagePath');
}

3.3 缩放图片

Future<void> scaleImage() async {
  final String imagePath = 'path_to_your_image.jpg';
  final double scale = 0.5; // 缩放比例

  final String scaledImagePath = await FlutterImageEditorPlugin.scaleImage(
    imagePath: imagePath,
    scale: scale,
  );

  print('Scaled image saved at: $scaledImagePath');
}

3.4 添加文本

Future<void> addTextToImage() async {
  final String imagePath = 'path_to_your_image.jpg';
  final String text = 'Hello, Flutter!';
  final TextOptions textOptions = TextOptions(
    position: Offset(50, 50), // 文本位置
    color: Colors.red, // 文本颜色
    fontSize: 24, // 字体大小
  );

  final String textImagePath = await FlutterImageEditorPlugin.addTextToImage(
    imagePath: imagePath,
    text: text,
    textOptions: textOptions,
  );

  print('Image with text saved at: $textImagePath');
}

3.5 添加贴纸

Future<void> addStickerToImage() async {
  final String imagePath = 'path_to_your_image.jpg';
  final String stickerPath = 'path_to_your_sticker.png';
  final Offset position = Offset(100, 100); // 贴纸位置

  final String stickerImagePath = await FlutterImageEditorPlugin.addStickerToImage(
    imagePath: imagePath,
    stickerPath: stickerPath,
    position: position,
  );

  print('Image with sticker saved at: $stickerImagePath');
}

4. 处理结果

上述方法都会返回处理后的图片路径,你可以使用 Image.file 来显示处理后的图片:

Image.file(File(croppedImagePath));

5. 注意事项

  • 确保你有读写外部存储的权限。
  • 处理大图片时可能会占用较多内存,建议在后台线程中进行处理。

6. 示例代码

以下是一个完整的示例,展示如何使用 flutter_image_editor_plugin 进行图片裁剪、旋转、缩放、添加文本和贴纸:

import 'package:flutter/material.dart';
import 'package:flutter_image_editor_plugin/flutter_image_editor_plugin.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ImageEditorDemo(),
    );
  }
}

class ImageEditorDemo extends StatefulWidget {
  [@override](/user/override)
  _ImageEditorDemoState createState() => _ImageEditorDemoState();
}

class _ImageEditorDemoState extends State<ImageEditorDemo> {
  String _imagePath = 'path_to_your_image.jpg';
  String _processedImagePath;

  Future<void> _cropImage() async {
    final Rect cropRect = Rect.fromLTWH(50, 50, 200, 200);
    _processedImagePath = await FlutterImageEditorPlugin.cropImage(
      imagePath: _imagePath,
      cropRect: cropRect,
    );
    setState(() {});
  }

  Future<void> _rotateImage() async {
    _processedImagePath = await FlutterImageEditorPlugin.rotateImage(
      imagePath: _imagePath,
      degrees: 90,
    );
    setState(() {});
  }

  Future<void> _scaleImage() async {
    _processedImagePath = await FlutterImageEditorPlugin.scaleImage(
      imagePath: _imagePath,
      scale: 0.5,
    );
    setState(() {});
  }

  Future<void> _addTextToImage() async {
    _processedImagePath = await FlutterImageEditorPlugin.addTextToImage(
      imagePath: _imagePath,
      text: 'Hello, Flutter!',
      textOptions: TextOptions(
        position: Offset(50, 50),
        color: Colors.red,
        fontSize: 24,
      ),
    );
    setState(() {});
  }

  Future<void> _addStickerToImage() async {
    _processedImagePath = await FlutterImageEditorPlugin.addStickerToImage(
      imagePath: _imagePath,
      stickerPath: 'path_to_your_sticker.png',
      position: Offset(100, 100),
    );
    setState(() {});
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Editor Demo'),
      ),
      body: Column(
        children: [
          if (_processedImagePath != null)
            Image.file(File(_processedImagePath)),
          ElevatedButton(
            onPressed: _cropImage,
            child: Text('Crop Image'),
          ),
          ElevatedButton(
            onPressed: _rotateImage,
            child: Text('Rotate Image'),
          ),
          ElevatedButton(
            onPressed: _scaleImage,
            child: Text('Scale Image'),
          ),
          ElevatedButton(
            onPressed: _addTextToImage,
            child: Text('Add Text to Image'),
          ),
          ElevatedButton(
            onPressed: _addStickerToImage,
            child: Text('Add Sticker to Image'),
          ),
        ],
      ),
    );
  }
}
回到顶部