Flutter图片裁剪插件image_cropper2的使用

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

Flutter图片裁剪插件image_cropper2的使用

插件简介

image_cropper2 是一个支持 Android、iOS 和 Web 的 Flutter 插件,用于裁剪图片。该插件基于三个不同的原生库(分别是 uCrop、TOCropViewController 和 croppie),因此在不同平台上具有不同的用户界面。

该插件基于 hnvn 的 image_cropper 插件开发,区别在于增加了 recoverImage 功能,允许恢复因 Android 活动终止而丢失的图片。(此功能是一个临时解决方案,直到原插件合并了相关拉取请求)。

介绍

Image Cropper 并不直接在 Dart 代码中处理图片,而是通过平台通道(Platform Channels)将 Dart API 暴露给 Flutter 应用程序,从而与强大的原生库(如 uCrop、TOCropViewController 和 croppie)进行通信以裁剪和旋转图片。因此,所有功劳归于这些库。

uCrop - Yalantis



该项目旨在提供终极且灵活的图片裁剪体验,由 Yalantis 开发。

uCrop 示例

TOCropViewController - TimOliver



TOCropViewController 是一个开源的 UIViewController 子类,用于从 UIImage 对象中裁剪部分图像,并执行基本的旋转操作。它非常适合编辑头像或在线分享照片的一部分。它的设计灵感来自 iOS 照片应用编辑器,因此用户界面会感觉非常熟悉。

TOCropViewController 示例

Croppie - Foliotek



Croppie 是一个快速、易于使用的图片裁剪插件,具有大量的配置选项!

Croppie 示例

如何安装

Android

  1. AndroidManifest.xml 中添加以下内容:
<activity
    android:name="com.yalantis.ucrop.UCropActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

注意:从 v1.2.0 开始,你需要将 Android 项目迁移到 v2 嵌入式(详情见 此处)。

iOS

无需任何配置。

Web

  1. web/index.html 文件的 <head> 标签内添加以下代码:
<head>
  ...

  <!-- Croppie -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.css" />
  <script defer src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.min.js"></script>

  ...
</head>

使用方法

必需参数

  • sourcePath: 图片文件的绝对路径。

可选参数

  • maxWidth: 裁剪后图片的最大宽度。注意:此字段在 Web 上被忽略。
  • maxHeight: 裁剪后图片的最大高度。注意:此字段在 Web 上被忽略。
  • aspectRatio: 控制裁剪区域的宽高比。如果设置了此值,则裁剪框会被锁定,用户无法更改宽高比。注意:此字段在 Web 上被忽略。
  • aspectRatioPresets: 控制裁剪菜单视图中的宽高比列表。在 Android 上,可以通过设置 AndroidUiSettings.initAspectRatio 来初始化裁剪的宽高比。注意:此字段在 Web 上被忽略。
  • cropStyle: 控制裁剪框的样式,可以是矩形或圆形(默认为 CropStyle.rectangle)。注意:此字段在 Web 上可以被 WebUiSettings.viewPort.type 覆盖。
  • compressFormat: 结果图片的格式,png 或 jpg(默认为 ImageCompressFormat.jpg)。
  • compressQuality: 0 到 100 之间的数字,用于控制图片压缩的质量。
  • uiSettings: 控制特定平台(Android、iOS、Web 等)的 UI 定制化。

注意事项

  • 结果文件保存在 iOS 的 <NSTemporaryDirectory> 和 Android 的应用程序缓存目录中,因此可能会丢失,你需要将其存储到永久位置(如果需要)。
  • Web 实现与移动应用实现有很大不同,这导致某些配置字段在 Web 上不起作用(如 maxWidthmaxHeightaspectRatioaspectRatioPresets)。
  • Web 上需要 WebUiSettings

自定义化

Android

Android 自定义化详细说明

属性 描述 类型
toolbarTitle 工具栏标题的文本 String
toolbarColor 工具栏的颜色 Color
statusBarColor 状态栏的颜色 Color
toolbarWidgetColor 工具栏文字和按钮的颜色(默认为更深的橙色) Color
backgroundColor 应用于根视图的背景颜色 Color
activeControlsWidgetColor 激活和选择的小部件和进度轮中间线的颜色(默认为白色) Color
dimmedLayerColor 裁剪框周围模糊区域的颜色 Color
cropFrameColor 裁剪框的颜色 Color
cropGridColor 裁剪网格/指南的颜色 Color
cropFrameStrokeWidth 裁剪框线条的宽度(单位为像素) int
cropGridRowCount 裁剪网格行数 int
cropGridColumnCount 裁剪网格列数 int
cropGridStrokeWidth 裁剪网格线条的宽度(单位为像素) int
showCropGrid 是否显示裁剪网格/指南 bool
lockAspectRatio 是否锁定裁剪框的宽高比(默认锁定) bool
hideBottomControls 是否隐藏底部控件(默认显示) bool
initAspectRatio 启动裁剪器时应用的宽高比(从给定的宽高比预设中选择) CropAspectRatioPreset

iOS

iOS 自定义化详细说明

属性 描述 类型
minimumAspectRatio 最小裁剪宽高比。如果设置,用户无法将裁剪矩形设置为低于此参数定义的宽高比 double
rectX 裁剪初始矩形的 x 坐标 double
rectY 裁剪初始矩形的 y 坐标 double
rectWidth 裁剪初始矩形的宽度 double
rectHeight 裁剪初始矩形的高度 double
showActivitySheetOnDone 如果为真,在用户点击 ‘完成’ 后,会出现 UIActivityController bool
showCancelConfirmationDialog 当用户点击 ‘取消’ 且有未保存更改时是否显示确认对话框(默认为 false) bool
rotateClockwiseButtonHidden 禁用时,工具栏中会显示一个额外的旋转按钮,可按 90 度顺时针旋转画布 bool
hidesNavigationBar 如果此控制器嵌套在 UINavigationController 中,默认隐藏导航栏 bool
rotateButtonsHidden 启用时隐藏旋转按钮及其替代按钮(默认为 false) bool
resetButtonHidden 启用时隐藏工具栏上的 ‘重置’ 按钮(默认为 false) bool
aspectRatioPickerButtonHidden 启用时隐藏工具栏上的 ‘宽高比选择器’ 按钮(默认为 false) bool
resetAspectRatioEnabled 如果为真,点击重置按钮将重置宽高比为默认值;否则仅缩放到当前宽高比 bool
aspectRatioLockDimensionSwapEnabled 如果为真,自定义宽高比已设置且 aspectRatioLockEnabled 设置为 true,则裁剪框将根据图片方向切换尺寸 bool
aspectRatioLockEnabled 如果为真,虽然仍可调整大小,但裁剪框将锁定其当前宽高比 bool
title 视图控制器顶部显示的标题文本 String
doneButtonTitle ‘完成’ 按钮的标题。设置此值将覆盖默认的本地化字符串 ‘完成’ String
cancelButtonTitle ‘取消’ 按钮的标题。设置此值将覆盖默认的本地化字符串 ‘取消’ String

Web

Web 自定义化详细说明

属性 描述 类型
boundary 裁剪器的外容器。默认值:{ width: 500, height: 500 } Boundary
viewPort 裁剪器的内容器。可见的图片部分。有效类型值:‘square’, ‘circle’。默认值:{ width: 400, height: 400, type: ‘square’ } ViewPort
customClass 添加到容器的自定义类,以便为其添加自定义样式。默认值:’’ String
enableExif 启用 exif 方向读取。告诉 Croppie 从图片数据中读取 exif 方向并正确渲染图片 bool
enableOrientation 启用或禁用指定自定义方向时绑定图片的支持。默认值:true bool
enableZoom 启用缩放功能。如果设置为 false,滚动和捏合不会缩放。默认值:false bool
enableResize 启用或禁用调整视口区域大小的支持。默认值:false bool
mouseWheelZoom 启用或禁用使用鼠标滚轮放大和缩小裁剪器实例的能力。默认值:true bool
showZoomer 隐藏或显示缩放滑块。默认值:true bool
presentStyle 裁剪器的呈现样式,可以是对话框或页面(路由)。默认值:dialog CropperPresentStyle
context 当前 BuildContext。显示裁剪对话框或路由时需要此上下文 BuildContext
customDialogBuilder 自定义裁剪对话框的构建器 CropperDialogBuilder
customRouteBuilder 自定义裁剪页面路由的构建器 CropperRouteBuilder

注意: 如果使用 CropperDialogBuilderCropperRouteBuilder 自定义裁剪对话框和路由,则自定义代码需要调用 crop() 函数来触发裁剪功能,并通过 Navigator.of(context).pop(result) 将结果数据返回给插件。

WebUiSettings(
  ...
  customDialogBuilder: (cropper, crop, rotate) {
    return Dialog(
      child: Builder(
        builder: (context) {
          return Column(
            children: [
              ...
              cropper,
              ...
              TextButton(
                onPressed: () async {
                  /// 调用 crop() 函数并将结果数据返回给插件
                  final result = await crop();
                  Navigator.of(context).pop(result);
                },
                child: Text('Crop'),
              )
            ]
          );
        },
      ),
    );
  },
  ...
)

示例代码

基本示例

import 'package:image_cropper/image_cropper.dart';

CroppedFile croppedFile = await ImageCropper().cropImage(
      sourcePath: imageFile.path,
      aspectRatioPresets: [
        CropAspectRatioPreset.square,
        CropAspectRatioPreset.ratio3x2,
        CropAspectRatioPreset.original,
        CropAspectRatioPreset.ratio4x3,
        CropAspectRatioPreset.ratio16x9
      ],
      uiSettings: [
        AndroidUiSettings(
            toolbarTitle: 'Cropper',
            toolbarColor: Colors.deepOrange,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.original,
            lockAspectRatio: false),
        IOSUiSettings(
          title: 'Cropper',
        ),
      ],
    );

Web 示例

Web 实现需要 WebUiSettings 对象,但由于此对象包含一些 JS 代码,因此不能在移动应用中编译。我们应使用条件导入来解决此问题。

例如:

import 'package:image_cropper/image_cropper.dart';

import 'cropper/ui_helper.dart'
    if (dart.library.io) 'cropper/mobile_ui_helper.dart'
    if (dart.library.html) 'cropper/web_ui_helper.dart';

CroppedFile croppedFile = await ImageCropper().cropImage(
      sourcePath: imageFile.path,
      aspectRatioPresets: [
        CropAspectRatioPreset.square,
        CropAspectRatioPreset.ratio3x2,
        CropAspectRatioPreset.original,
        CropAspectRatioPreset.ratio4x3,
        CropAspectRatioPreset.ratio16x9
      ],
      uiSettings: buildUiSettings(context),
    );

其中:

  • 文件 cropper/ui_helper.dart
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';

List<PlatformUiSettings>? buildUiSettings(BuildContext context) {
  throw UnimplementedError();
}
  • 文件 cropper/mobile_ui_helper.dart
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';

List<PlatformUiSettings>? buildUiSettings(BuildContext context) {
  return [
    AndroidUiSettings(
        toolbarTitle: 'Cropper',
        toolbarColor: Colors.deepOrange,
        toolbarWidgetColor: Colors.white,
        initAspectRatio: CropAspectRatioPreset.original,
        lockAspectRatio: false),
    IOSUiSettings(
      title: 'Cropper',
    ),
  ];
}
  • 文件 cropper/web_ui_helper.dart
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_cropper_for_web/image_cropper_for_web.dart';

List<PlatformUiSettings>? buildUiSettings(BuildContext context) {
  return [
    WebUiSettings(
      context: context,
      presentStyle: CropperPresentStyle.dialog,
      boundary: Boundary(
        width: 520,
        height: 520,
      ),
      viewPort: ViewPort(width: 480, height: 480, type: 'circle'),
      enableExif: true,
      enableZoom: true,
      showZoomer: true,
    ),
  ];
}

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

1 回复

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


image_cropper2 是一个用于 Flutter 的图片裁剪插件,它允许用户从图库或相机中选择图片,并进行裁剪。这个插件是 image_cropper 的一个分支,提供了更多的自定义选项和更好的兼容性。

安装

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

dependencies:
  flutter:
    sdk: flutter
  image_cropper2: ^1.0.0

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

基本用法

  1. 导入包

    import 'package:image_cropper2/image_cropper2.dart';
    import 'package:image_picker/image_picker.dart';
  2. 选择图片

    使用 image_picker 插件从图库或相机中选择图片。

    final ImagePicker _picker = ImagePicker();
    final XFile? imageFile = await _picker.pickImage(source: ImageSource.gallery);
  3. 裁剪图片

    使用 ImageCropper2.cropImage 方法对图片进行裁剪。

    if (imageFile != null) {
      final croppedFile = await ImageCropper2.cropImage(
        sourcePath: imageFile.path,
        aspectRatioPresets: [
          CropAspectRatioPreset.square,
          CropAspectRatioPreset.ratio3x2,
          CropAspectRatioPreset.original,
          CropAspectRatioPreset.ratio4x3,
          CropAspectRatioPreset.ratio16x9,
        ],
        uiSettings: [
          AndroidUiSettings(
            toolbarTitle: 'Cropper',
            toolbarColor: Colors.deepOrange,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.original,
            lockAspectRatio: false,
          ),
          IOSUiSettings(
            title: 'Cropper',
          ),
        ],
      );
    
      if (croppedFile != null) {
        // 使用裁剪后的图片
        final croppedImage = File(croppedFile.path);
        // 你可以在这里处理裁剪后的图片,比如显示在界面上或上传到服务器
      }
    }

参数说明

  • sourcePath: 要裁剪的图片路径。
  • aspectRatioPresets: 裁剪框的宽高比预设值。
  • uiSettings: 裁剪界面的 UI 设置,分为 Android 和 iOS 两种。

Android 和 iOS 的 UI 设置

  • Android:

    • toolbarTitle: 工具栏标题。
    • toolbarColor: 工具栏颜色。
    • toolbarWidgetColor: 工具栏上的控件颜色。
    • initAspectRatio: 初始的宽高比。
    • lockAspectRatio: 是否锁定宽高比。
  • iOS:

    • title: 裁剪界面的标题。

处理裁剪后的图片

裁剪后的图片会返回一个 File 对象,你可以将其保存到本地、显示在界面上或上传到服务器。

注意事项

  • 确保在 AndroidManifest.xmlInfo.plist 中添加了必要的权限和配置,以便访问相机和图库。
  • image_cropper2 是一个社区维护的插件,可能会有一些不稳定的地方,建议在使用前进行充分的测试。

示例代码

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

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

class _ImageCropperExampleState extends State<ImageCropperExample> {
  File? _image;

  Future<void> _pickAndCropImage() async {
    final ImagePicker _picker = ImagePicker();
    final XFile? imageFile = await _picker.pickImage(source: ImageSource.gallery);

    if (imageFile != null) {
      final croppedFile = await ImageCropper2.cropImage(
        sourcePath: imageFile.path,
        aspectRatioPresets: [
          CropAspectRatioPreset.square,
          CropAspectRatioPreset.ratio3x2,
          CropAspectRatioPreset.original,
          CropAspectRatioPreset.ratio4x3,
          CropAspectRatioPreset.ratio16x9,
        ],
        uiSettings: [
          AndroidUiSettings(
            toolbarTitle: 'Cropper',
            toolbarColor: Colors.deepOrange,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.original,
            lockAspectRatio: false,
          ),
          IOSUiSettings(
            title: 'Cropper',
          ),
        ],
      );

      if (croppedFile != null) {
        setState(() {
          _image = File(croppedFile.path);
        });
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Cropper Example'),
      ),
      body: Center(
        child: _image == null
            ? Text('No image selected.')
            : Image.file(_image!),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _pickAndCropImage,
        tooltip: 'Pick Image',
        child: Icon(Icons.add_a_photo),
      ),
    );
  }
}

void main() => runApp(MaterialApp(
  home: ImageCropperExample(),
));
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!