使用两个开发库,image_picker和image_crop。
前者用来拍照或者从相册选择照片,后者用来裁剪,结果均为File类型,裁剪完成后可以直接上传文件。
先写到这儿,有时间上代码。
更新:
实现的功能是点击头像图片,弹出选择框,选择拍照或者从相册中选取:
拍照或选取一张图片后,裁剪到想要大小。进行保存或者上传。
实现:
首先的首先,在Android的manifest文件中,加入网络、相机、文件读写的权限,并在application中加入一个activity声明。
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
首先在yaml文件中添加依赖:上https://pub.dartlang.org/packages/ flutter第三方插件官网,找最新版即可。添加之后 package get。
在调用的文件导入包,
import 'package:image_picker/image_picker.dart';
点击按钮,进行拍照:
///拍摄照片 Future getImage() async { await ImagePicker.pickImage(source: ImageSource.camera) .then((image) => cropImage(image)); }
通过相册选取:
///从相册选取 Future chooseImage() async { await ImagePicker.pickImage(source: ImageSource.gallery) .then((image) => cropImage(image)); }
.then拿到的是拍好的照片,之后进行跳转到剪裁页面CropImageRoute 进行剪裁。
void cropImage(File originalImage) async { String result = await Navigator.push(context, MaterialPageRoute(builder: (context) => CropImageRoute(originalImage))); if (result.isEmpty) { print('上传失败'); } else { //result是图片上传后拿到的url setState(() { iconUrl = result; print('上传成功:$iconUrl'); _upgradeRemoteInfo();//后续数据处理,这里是更新头像信息 }); } }
剪裁页面CropImageRoute 代码:
import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_productapp/home/moudel/upload_result.dart'; import 'package:flutter_productapp/home/util/screen.dart'; import 'package:flutter_productapp/base_ui/themes.dart'; import 'package:image_crop/image_crop.dart'; class CropImageRoute extends StatefulWidget { CropImageRoute(this.image); File image; //原始图片路径 @override _CropImageRouteState createState() => new _CropImageRouteState(); } class _CropImageRouteState extends State<CropImageRoute> { double baseLeft; //图片左上角的x坐标 double baseTop; //图片左上角的y坐标 double imageWidth; //图片宽度,缩放后会变化 double imageScale = 1; //图片缩放比例 Image imageView; final cropKey = GlobalKey<CropState>(); @override Widget build(BuildContext context) { return Scaffold( body: Container( height: Screen.height, width: Screen.width, color: ThemeColors.color333333, child: Column( children: <Widget>[ Container( height: Screen.height * 0.8, child: Crop.file( widget.image, key: cropKey, aspectRatio: 1.0, alwaysShowGrid: true, ), ), RaisedButton( onPressed: () { _crop(widget.image); }, child: Text('ok'), ), ], ), )); } Future<void> _crop(File originalFile) async { final crop = cropKey.currentState; final area = crop.area; if (area == null) { //裁剪结果为空 print('裁剪不成功'); } await ImageCrop.requestPermissions().then((value) { if (value) { ImageCrop.cropImage( file: originalFile, area: crop.area, ).then((value) { upload(value); }).catchError(() { print('裁剪不成功'); }); } else { upload(originalFile); } }); } ///上传头像 void upload(File file) { print(file.path); Dio dio = Dio(); dio .post("http://your ip:port/", data: FormData.from({'file': file})) .then((response) { if (!mounted) { return; } //处理上传结果 UploadIconResult bean = UploadIconResult(response.data); print('上传头像结果 $bean'); if (bean.code == '1') { Navigator.pop(context, bean.data.url);//这里的url在上一页调用的result可以拿到 } else { Navigator.pop(context, ''); } }); } }
至此,就可以基本实现了。
有啥问题欢迎指出。