Flutter图片裁剪插件images_crop的使用
Flutter图片裁剪插件images_crop的使用
一个用于在iOS和Android上进行图片裁剪的Flutter插件。
![Image Cropping Preview]
该插件包含一个Crop
小部件。该小部件仅渲染图像、覆盖层和处理程序以裁剪图像。因此它可以与其他小部件组合来构建自定义的图片裁剪体验。
该插件通过文件进行工作,以避免通过方法通道传递大量数据。文件存储在iOS和Android的缓存文件夹中。因此,如果需要保存实际裁剪后的图像,请确保将其复制到其他位置。
所有计算密集型工作都是通过iOS上的调度队列和Android上的缓存线程池在主线程之外完成的。
注意:此插件仍在开发中,部分功能尚未可用且测试有限。
安装
在pubspec.yaml
文件中添加image_crop
依赖项:
dependencies:
image_crop:
使用
创建一个小部件以加载和编辑图像:
final cropKey = GlobalKey<CropState>();
Widget _buildCropImage() {
return Container(
color: Colors.black,
padding: const EdgeInsets.all(20.0),
child: Crop(
key: cropKey,
image: Image.file(imageFile),
aspectRatio: 4.0 / 3.0,
),
);
}
访问裁剪值:
scale
是一个比例因子,用于按比例缩放裁剪图像的宽度和高度。1.0
表示不需要缩放。area
是一个矩形,指示要从图像中裁剪的分数位置。
final crop = cropKey.currentState;
// 或者
// final crop = Crop.of(context);
final scale = crop.scale;
final area = crop.area;
if (area == null) {
// 无法裁剪,小部件未设置好
// ...
}
访问和处理图像。作为方便函数,请求访问照片的权限:
final permissionsGranted = await ImageCrop.requestPermissions();
读取图像选项,例如:宽度和高度。这是一种高效的实现方式,不会解码或加载实际图像到内存中。
final options = await getImageOptions(file: file);
debugPrint('image width: ${options.width}, height: ${options.height}');
如果需要将大图像加载到内存中,有一个采样函数依赖于原生平台,在加载到内存之前按比例缩小图像。例如,将图像重新采样为尽可能接近1024x4096
尺寸。如果是一个正方形的preferredSize
可以用来指定宽度和高度。建议在显示图像时利用此功能。
final sampleFile = await ImageCrop.sampleImage(
file: originalFile,
preferredWidth: 1024,
preferredHeight: 4096,
);
一旦Crop
小部件准备好,就可以使用本机支持进行裁剪和缩放图像。为了生成高质量的裁剪图像,可以依赖于使用预设的最大宽度和高度进行采样图像。放大采样的图像分辨率。裁剪时,图像具有更高的分辨率。示例如下:
final sampledFile = await ImageCrop.sampleImage(
file: originalFile,
preferredWidth: (1024 / crop.scale).round(),
preferredHeight: (4096 / crop.scale).round(),
);
final croppedFile = await ImageCrop.cropImage(
file: sampledFile,
area: crop.area,
);
示例代码
以下是在example/lib/main.dart
中的完整示例代码:
import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:images_crop/images_crop.dart';
import 'package:image_picker/image_picker.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarBrightness: Brightness.dark,
statusBarIconBrightness: Brightness.light,
systemNavigationBarIconBrightness: Brightness.light,
));
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
final cropKey = GlobalKey<CropState>();
File? _file;
File? _sample;
File? _lastCropped;
[@override](/user/override)
void dispose() {
super.dispose();
_file?.delete();
_sample?.delete();
_lastCropped?.delete();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Container(
color: Colors.black,
padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 20.0),
child: _sample == null ? _buildOpeningImage() : _buildCroppingImage(),
),
),
);
}
Widget _buildOpeningImage() {
return Center(child: _buildOpenImage());
}
Widget _buildCroppingImage() {
return Column(
children: <Widget>[
Expanded(
child: Crop.file(_sample!, key: cropKey),
),
Container(
padding: const EdgeInsets.only(top: 20.0),
alignment: AlignmentDirectional.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TextButton(
child: Text(
'Crop Image',
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(color: Colors.white),
),
onPressed: () => _cropImage(),
),
_buildOpenImage(),
],
),
)
],
);
}
Widget _buildOpenImage() {
return TextButton(
child: Text(
'Open Image',
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(color: Colors.white),
),
onPressed: () => _openImage(),
);
}
Future<void> _openImage() async {
final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
if (pickedFile == null) return;
final file = File(pickedFile.path);
final sample = await ImageCrop.sampleImage(
file: file,
preferredSize: context.size?.longestSide.ceil(),
);
_sample?.delete();
_file?.delete();
setState(() {
_sample = sample;
_file = file;
});
}
Future<void> _cropImage() async {
final scale = cropKey.currentState?.scale ?? 1.0;
final area = cropKey.currentState?.area;
if (_file == null) {
// 无法裁剪,小部件未设置好
return;
}
if (area == null) {
// 无法裁剪,小部件未设置好
return;
}
// 放大到使用可能的最大像素数
// 这将在更高分辨率下采样图像以使裁剪图像更大
final sample = await ImageCrop.sampleImage(
file: _file!,
preferredSize: (2000 / scale).round(),
);
final file = await ImageCrop.cropImage(
file: sample,
area: area,
);
sample.delete();
_lastCropped?.delete();
_lastCropped = file;
debugPrint('$file');
}
}
更多关于Flutter图片裁剪插件images_crop的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html