Flutter图片编辑插件easy_image_editor的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter 图片编辑插件 easy_image_editor 的使用

Easy Image Editor

screenshot

EasyImageEditor 可以在背景图像或颜色上添加任何类型的部件,并移动这些部件、调整大小、旋转。

特性

  1. 更改编辑器背景颜色。
  2. 在编辑器中添加任何部件作为背景。
  3. 在编辑器上添加任何部件。
  4. 移动、调整大小、翻转、缩放和旋转已添加的部件。
  5. 使用另一个部件更新已添加的部件。
  6. 允许撤销和重做。
  7. 允许单选和多选。
  8. 允许更改边框颜色和移除图标。
  9. 删除已添加的部件。
  10. 手动处理所有操作。

开始使用

首先,在 pubspec.yaml 文件中将 easy_image_editor 添加为依赖项。

然后,在文件中导入 easy_image_editor 包:

import 'package:easy_image_editor/easy_image_editor.dart';

使用示例

以下是一个完整的示例代码,展示了如何使用 easy_image_editor 插件来编辑图片。

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:easy_image_editor/easy_image_editor.dart';
import 'dart:io';
import 'result.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late EasyImageEditorController _easyImageEditorController;
  final ImagePicker _picker = ImagePicker();

  final List<Color> _colorArray = [
    Colors.red,
    Colors.black,
    Colors.white,
    Colors.amber,
    Colors.black38,
    Colors.yellow,
    Colors.orange,
    Colors.deepOrange,
    Colors.pink,
    Colors.blue,
    Colors.cyan,
    Colors.deepPurple,
    Colors.teal,
  ];

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          IconButton(
            onPressed: () => _easyImageEditorController.canEditMultipleView(false),
            icon: const Icon(Icons.photo_size_select_large),
          ),
          IconButton(
            onPressed: () => _easyImageEditorController.canEditMultipleView(true),
            icon: const Icon(Icons.select_all),
          ),
          IconButton(
            onPressed: () => _easyImageEditorController.undo(),
            icon: const Icon(Icons.undo),
          ),
          IconButton(
            onPressed: () => _easyImageEditorController.redo(),
            icon: const Icon(Icons.redo),
          ),
          IconButton(
            onPressed: () {
              _easyImageEditorController.saveEditing().then((value) {
                if (value != null) {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (builder) => Result(uint8list: value)));
                }
              });
            },
            icon: const Icon(Icons.done_all),
          ),
        ],
      ),
      body: EditorView(
        borderColor: Colors.red,
        clickToFocusAndMove: false,
        onInitialize: (controller) {
          setState(() {
            _easyImageEditorController = controller;
          });
        },
        removeIcon: const Icon(
          Icons.cancel_outlined,
          size: 20.0,
        ),
        onViewTouchOver: (position, widget, widgetType) {
          debugPrint("onViewTouch: $position, $widgetType");
        },
        onClick: (position, widget, widgetType) {
          debugPrint("onViewClick");
          if (widgetType == "text") {
            Text _text = widget as Text;
            _addText(position, _text);
          }
        },
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.text_fields),
            label: "Add Text",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.image),
            label: "Add Image",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.color_lens),
            label: "Add Color",
          ),
        ],
        onTap: (position) {
          switch (position) {
            case 0:
              _addText(null, null);
              break;
            case 1:
              _addImage();
              break;
            case 2:
              _addBg();
              break;
          }
        },
      ),
    );
  }

  void _addText(int? position, Text? text) {
    final textEditController = TextEditingController(text: text?.data);
    Color? textColor = text?.style?.color;

    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(builder: (context, stateSetter) {
            return Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: TextField(
                    controller: textEditController,
                    keyboardType: TextInputType.text,
                    textInputAction: TextInputAction.done,
                    decoration: const InputDecoration(
                      hintText: "Enter Text",
                    ),
                    style: TextStyle(color: textColor),
                  ),
                ),
                SizedBox(
                  height: 60,
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemCount: _colorArray.length,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (context, index) {
                      return InkWell(
                        onTap: () {
                          stateSetter(() {
                            textColor = _colorArray[index];
                          });
                        },
                        child: Container(
                          height: 50.0,
                          width: 50.0,
                          color: _colorArray[index],
                        ),
                      );
                    },
                  ),
                ),
                InkWell(
                  onTap: () {
                    if (textEditController.text.isNotEmpty) {
                      Navigator.pop(context);

                      if (text == null) {
                        _easyImageEditorController.addView(
                          Text(
                            textEditController.text,
                            style: TextStyle(
                              fontSize: 20.0,
                              color: textColor,
                            ),
                          ),
                          widgetType: "text",
                        );
                      } else {
                        _easyImageEditorController.updateView(
                          position!,
                          Text(
                            textEditController.text,
                            style: TextStyle(
                              fontSize: 20.0,
                              color: textColor,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        );
                      }
                    }
                  },
                  child: Container(
                    width: 100.0,
                    margin: const EdgeInsets.all(20.0),
                    padding: const EdgeInsets.all(10.0),
                    decoration: BoxDecoration(
                        color: Theme.of(context).primaryColor,
                        borderRadius:
                            const BorderRadius.all(Radius.circular(10))),
                    child: const Center(
                      child: Text("Add"),
                    ),
                  ),
                ),
              ],
            );
          });
        });
  }

  _addBg() {
    showModalBottomSheet(
        context: context,
        builder: (context) {
          return SizedBox(
            height: 60,
            child: ListView.builder(
              shrinkWrap: true,
              itemCount: _colorArray.length,
              scrollDirection: Axis.horizontal,
              itemBuilder: (context, index) {
                return InkWell(
                  onTap: () {
                    Navigator.pop(context);
                    _easyImageEditorController
                        .addBackgroundColor(_colorArray[index]);
                  },
                  child: Container(
                    height: 50.0,
                    width: 50.0,
                    color: _colorArray[index],
                  ),
                );
              },
            ),
          );
        });
  }

  _addImage() {
    showModalBottomSheet(
        context: context,
        builder: (context) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              InkWell(
                onTap: () async {
                  final XFile? image =
                      await _picker.pickImage(source: ImageSource.gallery);
                  if (image != null) {
                    Navigator.pop(context);
                    _easyImageEditorController
                        .addBackgroundView(Image.file(File(image.path)));
                  }
                },
                child: const Padding(
                  padding: EdgeInsets.all(20),
                  child: Text(
                    "Set Background",
                    style: TextStyle(fontSize: 18.0),
                  ),
                ),
              ),
              InkWell(
                onTap: () async {
                  final XFile? image =
                      await _picker.pickImage(source: ImageSource.gallery);
                  if (image != null) {
                    Navigator.pop(context);
                    _easyImageEditorController.addView(
                        Image.file(
                          File(image.path),
                          height: 200,
                          width: 200,
                        ),
                        widgetType: "image");
                  }
                },
                child: const Padding(
                  padding: EdgeInsets.all(20),
                  child: Text(
                    "Add View",
                    style: TextStyle(fontSize: 18.0),
                  ),
                ),
              ),
            ],
          );
        });
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用easy_image_editor插件的示例代码。这个插件允许你对图片进行基本的编辑操作,比如裁剪、旋转、滤镜等。

首先,你需要在你的pubspec.yaml文件中添加easy_image_editor依赖:

dependencies:
  flutter:
    sdk: flutter
  easy_image_editor: ^latest_version  # 请替换为最新版本号

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

接下来,你可以在你的Flutter项目中使用EasyImageEditor组件。以下是一个完整的示例代码,展示了如何使用这个插件:

import 'package:flutter/material.dart';
import 'package:easy_image_editor/easy_image_editor.dart';
import 'package:image_picker/image_picker.dart';  // 用于选择图片

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Image Editor Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ImageEditorScreen(),
    );
  }
}

class ImageEditorScreen extends StatefulWidget {
  @override
  _ImageEditorScreenState createState() => _ImageEditorScreenState();
}

class _ImageEditorScreenState extends State<ImageEditorScreen> {
  File? imageFile;

  final ImagePicker _picker = ImagePicker();

  Future<void> pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.camera);

    if (pickedFile != null) {
      setState(() {
        imageFile = File(pickedFile.path);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Editor Demo'),
      ),
      body: Center(
        child: imageFile == null
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('No image selected.'),
                  ElevatedButton(
                    onPressed: pickImage,
                    child: Text('Pick Image'),
                  ),
                ],
              )
            : EasyImageEditor(
                image: imageFile!,
                cropAspectRatioPresets: [
                  CropAspectRatioPreset.square,
                  CropAspectRatioPreset.ratio3x2,
                  CropAspectRatioPreset.original,
                  CropAspectRatioPreset.ratio4x3,
                  CropAspectRatioPreset.ratio16x9
                ],
                onSave: (File editedImage) async {
                  // 处理保存后的图片
                  print('Saved image path: ${editedImage.path}');
                  // 可以在这里将图片上传到服务器或保存到本地
                },
              ),
      ),
    );
  }
}

在这个示例中:

  1. 我们首先使用ImagePicker从相机或图库中选择一张图片。
  2. 选择完图片后,我们将图片文件传递给EasyImageEditor组件。
  3. EasyImageEditor组件允许用户对图片进行编辑,比如裁剪、旋转等。
  4. 用户完成编辑后,可以通过onSave回调获取编辑后的图片文件。

请确保你已经添加了image_picker插件的依赖,因为它用于从设备中选择图片。同样,easy_image_editor的最新版本号可以在pub.dev网站上找到,并替换示例中的latest_version

这个示例展示了基本的图片编辑功能,你可以根据需求进一步扩展和自定义编辑功能。

回到顶部