Flutter图片裁剪插件sparrow_image_cropper的使用
Flutter图片裁剪插件sparrow_image_cropper的使用
Sparrow Image Cropper
是一个用于Android和iOS平台的Flutter插件,支持图片裁剪功能。该插件基于两个不同的原生库(uCrop
和 TOCropViewController
),因此在不同平台上具有不同的用户界面。
介绍
Image Cropper
不直接在Dart代码中处理图像,而是通过平台通道(Platform Channels)暴露给Flutter应用可以使用的API,以与两个非常强大的原生库(uCrop
和 TOCropViewController
)通信来裁剪和旋转图像。因此,所有功劳归于这些库。
uCrop - Yalantis

TOCropViewController - TimOliver

如何安装
Android
- 将
UCropActivity
添加到你的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
无需配置。
使用方法
必须参数
- sourcePath: 图像文件的绝对路径。
可选参数
- maxWidth: 裁剪后图像的最大宽度。
- maxHeight: 裁剪后图像的最大高度。
- aspectRatio: 控制裁剪边界的比例。如果设置此值,则裁剪器会被锁定,用户无法更改裁剪边界的比例。
- aspectRatioPresets: 控制裁剪菜单视图中的比例列表。在Android上,可以通过设置
AndroidUiSettings.initAspectRatio
的值来初始化裁剪时的比例。 - cropStyle: 控制裁剪边框的样式,可以是矩形或圆形(默认为
CropStyle.rectangle
)。 - compressFormat: 结果图像的格式,可以是png或jpg(默认为
ImageCompressFormat.jpg
)。 - compressQuality: 控制图像压缩质量的值 [0 - 100]。
- androidUiSettings: 控制Android上的UI自定义。详见Android自定义。
- iosUiSettings: 控制iOS上的UI自定义。详见iOS自定义。
注意:
结果文件保存在iOS的 NSTemporaryDirectory
和Android的应用程序缓存目录中,因此可能会丢失。如果你需要永久保存,需要自己负责存储。
自定义
Android
Image Cropper
提供了一个名为 AndroidUiSettings
的辅助类,该类封装了可以在 uCrop
库中自定义UI的所有属性。
属性名称 | 描述 | 类型 |
---|---|---|
toolbarTitle |
想要的工具栏标题文本 | 字符串 |
toolbarColor |
工具栏的颜色 | 颜色 |
statusBarColor |
状态栏的颜色 | 颜色 |
toolbarWidgetColor |
工具栏文本和按钮的颜色(默认是更深的橙色) | 颜色 |
backgroundColor |
应用到根视图的背景颜色 | 颜色 |
activeControlsWidgetColor |
活动和选定小部件及进度轮中间线的颜色(默认是白色) | 颜色 |
dimmedLayerColor |
裁剪边界周围的暗化区域的颜色 | 颜色 |
cropFrameColor |
裁剪边框的颜色 | 颜色 |
cropGridColor |
裁剪网格/指导线的颜色 | 颜色 |
cropFrameStrokeWidth |
裁剪边框线的宽度(像素) | 整数 |
cropGridRowCount |
裁剪网格行数 | 整数 |
cropGridColumnCount |
裁剪网格列数 | 整数 |
cropGridStrokeWidth |
裁剪网格线的宽度(像素) | 整数 |
showCropGrid |
如果为真,则会在图像顶部显示裁剪网格/指导线 | 布尔值 |
lockAspectRatio |
如果为真,则锁定裁剪边界的固定比例(默认锁定) | 布尔值 |
hideBottomControls |
如果为真,则隐藏底部控件(默认显示) | 布尔值 |
initAspectRatio |
开始裁剪时应用的所需比例(来自给定的比例预设列表) | CropAspectRatioPreset |
iOS
Image Cropper
提供了一个名为 IOSUiSettings
的辅助类,该类封装了可以在 TOCropViewController
库中自定义UI的所有属性。
属性名称 | 描述 | 类型 |
---|---|---|
minimumAspectRatio |
最小裁剪比例。如果设置,用户将被阻止设置低于此参数定义的裁剪矩形比例 | 浮点数 |
rectX |
初始裁剪矩形的x坐标 | 浮点数 |
rectY |
初始裁剪矩形的y坐标 | 浮点数 |
rectWidth |
初始裁剪矩形的宽度 | 浮点数 |
rectHeight |
初始裁剪矩形的高度 | 浮点数 |
showActivitySheetOnDone |
如果为真,在用户点击“完成”后,会先出现一个 UIActivityController ,然后再结束视图控制器 |
布尔值 |
showCancelConfirmationDialog |
当用户点击“取消”且有未保存更改时,显示确认对话框(默认为假) | 布尔值 |
rotateClockwiseButtonHidden |
如果禁用,则在工具栏中显示一个额外的旋转按钮,可以按90度顺时针方向旋转画布(默认为假) | 布尔值 |
hidesNavigationBar |
如果控制器嵌入在 UINavigationController 中,默认隐藏导航栏。设置为假以显示导航栏。必须在控制器展示之前设置 |
布尔值 |
rotateButtonsHidden |
如果启用,隐藏旋转按钮以及当 showClockwiseRotationButton 设置为YES时可见的替代旋转按钮(默认为假) |
布尔值 |
resetButtonHidden |
如果启用,隐藏工具栏中的“重置”按钮(默认为假) | 布尔值 |
aspectRatioPickerButtonHidden |
如果启用,隐藏工具栏中的“比例选择”按钮(默认为假) | 布尔值 |
resetAspectRatioEnabled |
如果为真,点击重置按钮也将把比例重置回图像的原始比例。否则,重置只会缩放到当前比例。如果设置为假,并且 aspectRatioLockEnabled 为真,则比例按钮将自动从工具栏中隐藏(默认为真) |
布尔值 |
aspectRatioLockDimensionSwapEnabled |
如果为真,设置了自定义比例,并且 aspectRatioLockEnabled 为真,则裁剪框将根据横向或纵向的图像尺寸交换其尺寸。此值还控制当图像旋转时是否可以交换尺寸(默认为假) |
布尔值 |
aspectRatioLockEnabled |
如果为真,虽然仍然可以调整大小,但裁剪框将锁定在其当前比例。如果设置为真,并且 resetAspectRatioEnabled 为假,则比例按钮将自动从工具栏中隐藏(默认为假) |
布尔值 |
title |
视图控制器顶部显示的标题文本 | 字符串 |
doneButtonTitle |
“完成”按钮的标题。设置此值将覆盖默认的本地化字符串“完成” | 字符串 |
cancelButtonTitle |
“取消”按钮的标题。设置此值将覆盖默认的本地化字符串“取消” | 字符串 |
示例
以下是一个完整的示例,展示了如何使用 sparrow_image_cropper
插件进行图片裁剪。
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:sparrow_image_cropper/sparrow_image_cropper.dart';
import 'package:sparrow_image_picker/sparrow_image_picker.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'ImageCropper',
theme: ThemeData.light().copyWith(primaryColor: Colors.deepOrange),
home: MyHomePage(
title: 'ImageCropper',
),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({required this.title});
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
enum AppState {
free,
picked,
cropped,
}
class _MyHomePageState extends State<MyHomePage> {
late AppState state;
File? imageFile;
[@override](/user/override)
void initState() {
super.initState();
state = AppState.free;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: imageFile != null ? Image.file(imageFile!) : Container(),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrange,
onPressed: () {
if (state == AppState.free)
_pickImage();
else if (state == AppState.picked)
_cropImage();
else if (state == AppState.cropped) _clearImage();
},
child: _buildButtonIcon(),
),
);
}
Widget _buildButtonIcon() {
if (state == AppState.free)
return Icon(Icons.add);
else if (state == AppState.picked)
return Icon(Icons.crop);
else if (state == AppState.cropped)
return Icon(Icons.clear);
else
return Container();
}
Future<void> _pickImage() async {
final pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
imageFile = pickedImage != null ? File(pickedImage.path) : null;
if (imageFile != null) {
setState(() {
state = AppState.picked;
});
}
}
Future<void> _cropImage() async {
File? croppedFile = await ImageCropper.cropImage(
sourcePath: imageFile!.path,
aspectRatioPresets: Platform.isAndroid
? [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
]
: [
CropAspectRatioPreset.original,
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio5x3,
CropAspectRatioPreset.ratio5x4,
CropAspectRatioPreset.ratio7x5,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: Colors.deepOrange,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
iosUiSettings: IOSUiSettings(
title: 'Cropper',
));
if (croppedFile != null) {
imageFile = croppedFile;
setState(() {
state = AppState.cropped;
});
}
}
void _clearImage() {
imageFile = null;
setState(() {
state = AppState.free;
});
}
}
更多关于Flutter图片裁剪插件sparrow_image_cropper的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图片裁剪插件sparrow_image_cropper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter中的sparrow_image_cropper
插件进行图片裁剪的代码示例。这个插件允许用户在Flutter应用中裁剪图像。
步骤1:添加依赖
首先,你需要在pubspec.yaml
文件中添加sparrow_image_cropper
的依赖:
dependencies:
flutter:
sdk: flutter
sparrow_image_cropper: ^x.y.z # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
步骤2:导入插件
在你的Dart文件中导入sparrow_image_cropper
插件:
import 'package:sparrow_image_cropper/sparrow_image_cropper.dart';
步骤3:使用插件
下面是一个完整的示例,展示如何使用sparrow_image_cropper
进行图片裁剪:
import 'package:flutter/material.dart';
import 'package:sparrow_image_cropper/sparrow_image_cropper.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Image Cropper Example'),
),
body: ImageCropperPage(),
),
);
}
}
class ImageCropperPage extends StatefulWidget {
@override
_ImageCropperPageState createState() => _ImageCropperPageState();
}
class _ImageCropperPageState extends State<ImageCropperPage> {
File? _imageFile;
CroppedFile? _croppedFile;
final ImagePicker _picker = ImagePicker();
Future<void> _pickImage() async {
final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
_imageFile = File(pickedFile.path);
});
// 打开裁剪页面
_cropImage();
}
}
Future<void> _cropImage() async {
if (_imageFile == null) return;
final croppedFile = await SparrowImageCropper.cropImage(
sourcePath: _imageFile!.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: Colors.deepOrange,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
),
);
setState(() {
if (croppedFile == null) return;
_croppedFile = croppedFile;
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Original Image:'),
_imageFile == null
? Text('No image selected.')
: Image.file(_imageFile!, width: 300, fit: BoxFit.cover),
SizedBox(height: 20),
Text('Cropped Image:'),
_croppedFile == null
? Text('No cropped image available.')
: Image.file(_croppedFile!.path, width: 300, fit: BoxFit.cover),
SizedBox(height: 20),
ElevatedButton(
onPressed: _pickImage,
child: Text('Pick Image'),
),
],
),
);
}
}
注意事项
- 权限处理:确保在Android和iOS平台上请求必要的存储权限。
- 依赖冲突:如果与其他图像选择或裁剪插件有冲突,请检查依赖版本和兼容性。
- 错误处理:添加适当的错误处理,例如用户取消选择图像或裁剪操作失败时的处理。
这个示例展示了如何从图库中选择图像,并使用sparrow_image_cropper
进行裁剪,然后显示原始图像和裁剪后的图像。希望这个示例对你有所帮助!