Flutter——头像上传功能,实现照片选择及裁剪
2020-02-15 本文已影响0人
小宇宙_fly
使用两个开发库,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, '');
}
});
}
}
————————————————