Flutter图片裁剪插件image_crop的使用
Flutter 图片裁剪插件 image_crop 的使用
简介
image_crop
是一个用于在 iOS 和 Android 平台上裁剪图片的 Flutter 插件。
该插件包含一个 Crop
小部件。此小部件仅渲染图片、覆盖层和处理程序以裁剪图片。因此,它可以与其他小部件组合以构建自定义的图片裁剪体验。
该插件通过文件来工作,以避免通过方法通道传递大量数据。文件存储在 iOS 和 Android 的缓存文件夹中。因此,如果需要保存实际裁剪后的图片,请确保将文件复制到其他位置。
所有计算密集型工作都在主线程之外通过 iOS 上的调度队列和 Android 上的缓存线程池完成。
注意:该插件仍在开发中,某些功能尚不可用且测试有限。
安装
在 pubspec.yaml
文件中添加 image_crop
依赖项:
dependencies:
image_crop: ^0.3.0
然后运行 flutter pub get
来获取新的依赖项。
使用
创建一个用于加载和编辑图片的小部件:
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
的尺寸。
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,
);
示例代码
以下是一个完整的示例代码,展示了如何使用 image_crop
插件进行图片裁剪。
import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_crop/image_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
.button
.copyWith(color: Colors.white),
),
onPressed: () => _cropImage(),
),
_buildOpenImage(),
],
),
)
],
);
}
Widget _buildOpenImage() {
return TextButton(
child: Text(
'Open Image',
style: Theme.of(context).textTheme.button.copyWith(color: Colors.white),
),
onPressed: () => _openImage(),
);
}
Future<void> _openImage() async {
final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
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;
final area = cropKey.currentState.area;
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图片裁剪插件image_crop的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图片裁剪插件image_crop的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用image_crop
插件进行图片裁剪的详细代码示例。需要注意的是,image_crop
插件可能指的是image_cropper
插件,这是Flutter社区中比较流行的一个图片裁剪插件。如果你确实是指另一个插件,请确保名称正确,并参考其官方文档。以下示例将基于image_cropper
插件进行说明。
首先,确保在你的pubspec.yaml
文件中添加image_cropper
依赖:
dependencies:
flutter:
sdk: flutter
image_cropper: ^x.x.x # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们编写代码来实现图片裁剪功能。以下是一个完整的示例,包括选择图片、裁剪图片以及显示裁剪后的图片。
import 'package:flutter/material.dart';
import 'package:image_cropper/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(
title: 'Flutter Image Cropper Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ImageCropperScreen(),
);
}
}
class ImageCropperScreen extends StatefulWidget {
@override
_ImageCropperScreenState createState() => _ImageCropperScreenState();
}
class _ImageCropperScreenState extends State<ImageCropperScreen> {
File? _imageFile;
CroppedImage? _croppedImage;
final ImagePicker _picker = ImagePicker();
Future<void> _pickImage() async {
final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
File? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedFile.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,
),
);
if (croppedFile != null) {
setState(() {
_croppedImage = CroppedImage.fromFile(croppedFile);
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Cropper Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_imageFile != null
? Image.file(
_imageFile!,
fit: BoxFit.cover,
width: 300,
height: 300,
)
: Container(),
_croppedImage != null
? Image.file(
File(_croppedImage!.path),
fit: BoxFit.cover,
width: 300,
height: 300,
)
: Container(),
SizedBox(height: 20),
ElevatedButton(
onPressed: _pickImage,
child: Text('Pick and Crop Image'),
),
],
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 使用
ImagePicker
从设备的图库中选择图片。 - 使用
ImageCropper
裁剪选择的图片。 - 显示原始图片和裁剪后的图片。
注意:
- 在实际项目中,你可能需要处理更多的错误和边缘情况。
- 裁剪后的图片会存储在设备的临时目录中,你可以根据需要将其保存到永久存储位置。
- 请确保在
AndroidManifest.xml
和Info.plist
中添加必要的权限,以便访问设备的图库和存储。
希望这个示例能帮助你理解如何在Flutter项目中使用image_cropper
插件进行图片裁剪。