Flutter图片裁剪插件image_cropper2的使用
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 开发。
TOCropViewController - TimOliver
TOCropViewController
是一个开源的 UIViewController
子类,用于从 UIImage
对象中裁剪部分图像,并执行基本的旋转操作。它非常适合编辑头像或在线分享照片的一部分。它的设计灵感来自 iOS 照片应用编辑器,因此用户界面会感觉非常熟悉。
Croppie - Foliotek
Croppie 是一个快速、易于使用的图片裁剪插件,具有大量的配置选项!
如何安装
Android
- 在
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
- 在
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 上不起作用(如
maxWidth
、maxHeight
、aspectRatio
、aspectRatioPresets
)。 - 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 |
注意:
如果使用 CropperDialogBuilder
和 CropperRouteBuilder
自定义裁剪对话框和路由,则自定义代码需要调用 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
更多关于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
来安装依赖。
基本用法
-
导入包:
import 'package:image_cropper2/image_cropper2.dart'; import 'package:image_picker/image_picker.dart';
-
选择图片:
使用
image_picker
插件从图库或相机中选择图片。final ImagePicker _picker = ImagePicker(); final XFile? imageFile = await _picker.pickImage(source: ImageSource.gallery);
-
裁剪图片:
使用
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.xml
和Info.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(),
));