Flutter图片裁剪插件picture_cropper的使用
Flutter图片裁剪插件picture_cropper的使用
简介
picture_cropper
是一个用于Flutter的图片裁剪插件,它支持从相机拍摄照片或从相册选择图片,并提供多种编辑功能。本文将详细介绍如何在Flutter项目中集成和使用该插件。
插件特点
- 从相机拍摄照片
- 从相册选择图片
- 提供多种裁剪模式(如二维码、竖版卡片、横版卡片等)
- 支持图片的基本编辑功能(旋转、缩放、滤镜等)
安装
首先,在你的 pubspec.yaml
文件中添加 picture_cropper
作为依赖项:
dependencies:
picture_cropper: ^latest_version
然后导入 Dart 代码:
import 'package:picture_cropper/picture_cropper.dart';
iOS 配置
在 Info.plist
文件中添加以下权限配置:
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to demonstrate image picker plugin</string>
<key>NSCameraUsageDescription</key>
<string>Used to demonstrate image picker plugin</string>
<key>NSMicrophoneUsageDescription</key>
<string>Used to capture audio for image picker plugin</string>
Android 配置
无需额外配置。
示例代码
下面是一个完整的示例,展示了如何使用 picture_cropper
插件进行图片的选择和裁剪。
主页面示例
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:picture_cropper/picture_cropper.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Picture Editor Sample',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => const MyHomePage(),
'/editor': (context) => const EditorPage(),
},
onGenerateRoute: (settings) {
if (settings.name == '/crop') {
final image = settings.arguments as ui.Image;
return MaterialPageRoute(
builder: (context) {
return CropImagePage(image: image);
},
);
}
assert(false, 'Need to implement ${settings.name}');
return null;
},
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final pictureCropperController = PictureCropperController(isPicker: true);
int _cropStatus = 0; // 0 = qr, 1 = vertical card, 2 = card, 3 = clear
bool _isLoading = false;
void isLoading(bool value) {
_isLoading = value;
setState(() {});
}
[@override](/user/override)
void dispose() {
pictureCropperController.pictureEditorControllerDispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Stack(
children: [
Center(
child: PicturePicker(
controller: pictureCropperController,
onSetOriginalImage: () async {
final result = await Navigator.pushNamed(context, '/editor');
if (result == true) {
pictureCropperController.changeCropGuidelineType(
pictureCropperController.cropGuidelineType);
}
},
),
),
Container(
padding: const EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
setState(() {
_cropStatus = 0;
pictureCropperController
.changeCropGuidelineType(CropGuideLineType.qr);
});
},
child: Icon(
Icons.crop_din,
color: _cropStatus == 0 ? Colors.blue : Colors.white,
size: 32,
),
),
InkWell(
onTap: () {
setState(() {
_cropStatus = 1;
pictureCropperController.changeCropGuidelineType(
CropGuideLineType.verticalCard);
});
},
child: Icon(
Icons.crop_portrait,
color: _cropStatus == 1 ? Colors.blue : Colors.white,
size: 32,
),
),
InkWell(
onTap: () {
setState(() {
_cropStatus = 2;
pictureCropperController
.changeCropGuidelineType(CropGuideLineType.card);
});
},
child: Icon(
Icons.crop_3_2,
color: _cropStatus == 2 ? Colors.blue : Colors.white,
size: 32,
),
),
InkWell(
onTap: () {
setState(() {
_cropStatus = 3;
pictureCropperController
.changeCropGuidelineType(CropGuideLineType.clear);
});
},
child: Icon(
Icons.not_interested,
color: _cropStatus == 3 ? Colors.blue : Colors.white,
size: 32,
),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () async {
isLoading(true);
await pictureCropperController.pickImageFromGallery();
isLoading(false);
},
child: const Icon(
Icons.photo,
color: Colors.white,
size: 32,
),
),
InkWell(
onTap: () async {
isLoading(true);
await pictureCropperController.takePicture();
isLoading(false);
},
child: const Icon(
Icons.camera,
color: Colors.white,
size: 64,
),
),
InkWell(
onTap: pictureCropperController.toggleCameraDirection,
child: const Icon(
Icons.change_circle,
color: Colors.white,
size: 32,
),
),
],
),
),
),
Visibility(
visible: _isLoading,
child: Stack(
children: <Widget>[
Opacity(
opacity: 0.5,
child: Container(
color: Colors.black,
width: double.infinity,
height: double.infinity,
),
),
const Padding(
padding: EdgeInsets.only(bottom: 16),
child: Center(
child: CircularProgressIndicator(color: Colors.blue),
),
),
],
),
),
],
),
),
);
}
}
编辑页面示例
import 'package:flutter/material.dart';
import 'package:picture_cropper/picture_cropper.dart';
class EditorPage extends StatelessWidget {
const EditorPage({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
final pictureCropperController = PictureCropperController();
return Scaffold(
body: SafeArea(
child: PictureEditor(
controller: pictureCropperController,
onCropComplete: (image) {
Navigator.pushNamed(context, '/crop', arguments: image);
},
),
),
);
}
}
裁剪结果页面示例
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
class CropImagePage extends StatelessWidget {
final ui.Image image;
const CropImagePage({required this.image, super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cropped Image'),
),
body: Center(
child: Image(image: Image.memory(image.toByteData().buffer.asUint8List()).image),
),
);
}
}
更多关于Flutter图片裁剪插件picture_cropper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图片裁剪插件picture_cropper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用picture_cropper
插件进行图片裁剪的示例代码。这个插件允许用户从相机或图库中选取图片,并进行裁剪。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加picture_cropper
依赖:
dependencies:
flutter:
sdk: flutter
picture_cropper: ^2.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Dart文件中导入picture_cropper
插件:
import 'package:picture_cropper/picture_cropper.dart';
import 'package:image_picker/image_picker.dart'; // 用于选择图片
3. 配置权限
在AndroidManifest.xml
中添加必要的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
对于iOS,需要在Info.plist
中添加权限描述:
<key>NSCameraUsageDescription</key>
<string>Need camera access</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Need photo library access</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access</string>
4. 编写代码
下面是一个完整的示例,展示如何使用picture_cropper
插件:
import 'package:flutter/material.dart';
import 'package:picture_cropper/picture_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('Picture Cropper Example'),
),
body: Center(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ImagePicker _picker = ImagePicker();
late File? _imageFile;
Future<void> _pickImage() async {
final XFile? image = await _picker.pickImage(source: ImageSource.camera);
if (image != null && image.path != null) {
final File croppedFile = await _cropImage(File(image.path!));
setState(() {
_imageFile = croppedFile;
});
}
}
Future<File> _cropImage(File imageFile) async {
final CropperController cropperController = CropperController();
final CroppedFile croppedFile = await PictureCropper.cropImage(
sourcePath: imageFile.absolute.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,
),
cropperController: cropperController,
);
if (croppedFile != null) {
return File(croppedFile.path);
} else {
throw Exception('Crop failed.');
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _pickImage,
child: Text('Pick and Crop Image'),
),
if (_imageFile != null)
Image.file(
_imageFile!,
width: 300,
height: 300,
fit: BoxFit.cover,
),
],
);
}
}
5. 运行应用
现在你可以运行你的Flutter应用,点击按钮从相机中选择图片并进行裁剪。裁剪后的图片会显示在界面上。
这个示例展示了基本的图片选择和裁剪功能,你可以根据需要进一步自定义和扩展。