在实际任务中免不了对图片进行裁切 文件格式转换 图片的选取等操作 这里做一个记录
1. Flutter 图片选择工具 image_picker
2. 图片裁切工具 image_cropper
3. 图片保存到相册image_gallery_saver
图片选择器
介绍
这里我选择的是image_picker
优点
- 官方出品的插件
- 可以直接调用相册和相机无需提前申请权限
- 可以多选和单选选择丰富
缺点 - 多选需要长按没有明显的提示
使用
- 引用组件
- 封装他的一个方法(以单选为例子)
enum ImageFrom{
camera,
gallery
}
///选择一个图片
///[from] 是相机还是图库
///可选参数
///[maxWidth] 宽度,
///[maxHeight] 高度,
///[imageQuality] 质量
static pickSinglePic(ImageFrom from,
{double? maxWidth, double? maxHeight, int? imageQuality}) async {
ImageSource source;
switch (from) {
case ImageFrom.camera:
source = ImageSource.camera;
break;
case ImageFrom.gallery:
source = ImageSource.gallery;
break;
}
final pickerImages = await ImagePicker().pickImage(
source: source,
imageQuality: imageQuality,
maxWidth: maxWidth,
maxHeight: maxHeight,
);
return pickerImages;
}
使用:
final pickerImages = await ImageUtil.pickSinglePic(score);
图片裁切
使用
- 引用组件
2.在AndroidMainifest中增加一个View
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
- 封装成一个方法
///裁切图片
///[image] 图片路径或文件
///[width] 宽度
///[height] 高度
///[aspectRatio] 比例
///[androidUiSettings]UI 参数
///[iOSUiSettings] ios的ui 参数
static cropImage(
{required image,
required width,
required height,
aspectRatio,
androidUiSettings,
iOSUiSettings}) async {
String imagePth = "";
if (image is String) {
imagePth = image;
} else if (image is File) {
imagePth = image.path;
} else {
throw ("文件路径错误");
}
final croppedFile = await ImageCropper().cropImage(
sourcePath: imagePth,
maxWidth: FormatUtil.num2int(width),
maxHeight: FormatUtil.num2int(height),
aspectRatio: aspectRatio ??
CropAspectRatio(
ratioX: FormatUtil.num2double(width),
ratioY: FormatUtil.num2double(height)),
uiSettings: [
androidUiSettings ??
AndroidUiSettings(
toolbarTitle:
'图片裁切(${FormatUtil.num2int(width)}*${FormatUtil.num2int(height)})',
toolbarColor: Colors.blue,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
hideBottomControls: false,
lockAspectRatio: true),
iOSUiSettings ??
IOSUiSettings(
title: 'Cropper',
),
],
);
return croppedFile;
}
///数字转成Int
///[number] 可以是String 可以是int 可以是double 出错了就返回0;
static num2int(number) {
try {
if (number is String) {
return int.parse(number);
} else if (number is int) {
return number;
} else if (number is double) {
return number.toInt();
} else {
return 0;
}
} catch (e) {
return 0;
}
}
///数字转成double
///[number] 可以是String 可以是int 可以是double 出错了就返回0;
static num2double(number) {
try {
if (number is String) {
return double.parse(number);
} else if (number is int) {
return number.toDouble();
} else if (number is double) {
return number;
} else {
return 0.0;
}
} catch (e) {
return 0.0;
}
}
使用
File? _userImage = File(pickerImages.path);
if (_userImage != null) {
final croppedFile = await ImageUtil.cropImage(
image: _userImage,
width: 256,
height: 512);
}
图片保存
- 引入插件
2.封装组件
///保存Uint8List 到相册
///[image]Uint8List 数组
///[quality] 质量
///[name] 保存的名字
static saveImage2Album(image, {quality = 100, name = "photo"}) async {
final result =
await ImageGallerySaver.saveImage(image, quality: quality, name: name);
return result;
}
他还有一个保存文件的方法
_saveVideo() async {
var appDocDir = await getTemporaryDirectory();
String savePath = appDocDir.path + "/temp.mp4";
await Dio().download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4", savePath);
final result = await ImageGallerySaver.saveFile(savePath);
print(result);
}
使用
保存前注意先申请一下存储权限
PermissionUtil.checkPermission(
permissionList: [Permission.photos, Permission.storage],
onFailed: () => {ToastUtil().showCenterToast("图片处理错误")},
onSuccess: () async {
final result = await FileUtil.saveImage2Album(finalImgBuffer!,
quality: 100, name: "photo");
if (result != null) {
ToastUtil().showCenterToast("保存成功~~~");
} else {
ToastUtil().showCenterToast("保存失败~~~");
}
});
网友评论