在实际任务中免不了对图片进行裁切 文件格式转换 图片的选取等操作 这里做一个记录
1. Flutter 图片选择工具 image_picker
2. 图片裁切工具 image_cropper
3. 图片保存到相册image_gallery_saver

图片选择器

介绍

这里我选择的是image_picker
优点

  • 官方出品的插件
  • 可以直接调用相册和相机无需提前申请权限
  • 可以多选和单选选择丰富
    缺点
  • 多选需要长按没有明显的提示

使用

  1. 引用组件
  2. 封装他的一个方法(以单选为例子)
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);

图片裁切

使用

  1. 引用组件
  2. 在AndroidMainifest中增加一个View
       <activityandroid:name="com.yalantis.ucrop.UCropActivity"android:screenOrientation="portrait"android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
  1. 封装成一个方法
  ///裁切图片///[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);
}

图片保存

  1. 引入插件
  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("保存失败~~~");}});

Flutter 中对 图片文件的操作

图片间格式的转换等操作

图片文件转换成Base64

转换思路 File=>Uint8List =>Base64
使用场景:有些接口需要多图片上传使用base64进行多组图片上传操作

  ///文件转 Uint8Liststatic file2Uint8List(File file) async {Uint8List imageBytes = await file.readAsBytes();return imageBytes;}/// unit8List 转base64static uint8List2Base64(Uint8List uint8list) {String base64 = base64Encode(uint8list);return base64;}

Base64转dart.ui中的Image

使用场景:从接口获取的base64要画在Canvas上需要转换的格式

import 'dart:ui' as ui;///base64 转成需要的Image文件 这个Image是UI 下面的Image和Image widget不同 !!!///[asset] base64 无头字符串///[width]宽度///[height] 高度static Future<ui.Image> base64ToImage(String asset, {width, height}) async {Uint8List bytes = base64Decode(asset);ui.Codec codec = await ui.instantiateImageCodec(bytes,targetWidth: width, targetHeight: height);ui.FrameInfo fi = await codec.getNextFrame();return fi.image;}

用Canvas绘画

用 recorder 记录绘画的结果保存Picture

    ///canvas的记录工具 用来保存canvas的final recorder = ui.PictureRecorder();///canvas 绘图工具Canvas canvas = Canvas(recorder);///画笔 颜色为传入颜色 状态是填充Paint paint = Paint();paint.color = bgColor;paint.style = PaintingStyle.fill;///底下跟我画个背景canvas.drawRect(Rect.fromLTWH(0, 0, width, height), paint);///顶上再画个人paint.color = Colors.black;paint.style = PaintingStyle.stroke;paint.strokeWidth = 10;ui.Image image = await base64ToImage(imageFile,width: width.toInt(), height: height.toInt());canvas.drawImage(image, Offset.zero, paint);// 转换成图片///记录画的canvasPicture picture = recorder.endRecording();

将Picture 转换成ByteData

最终转换成 Uint8List 显示在屏幕上

  ///获取到的picture 转换成 ByteData///[picture] canvas画然后记录的文件///[width] 宽度///[height] 高度static Future<ByteData?> picture2ByteData(ui.Picture picture, double width, double height) async {ui.Image img = await picture.toImage(width.toInt(), height.toInt());debugPrint('img的尺寸: $img');ByteData? byteData = await img.toByteData(format: ui.ImageByteFormat.png);return byteData;}

将ByteData 转成 Uint8List

作用是可以显示在ImageWidget上 或者后续转成Base64 或者直接保存到本地

/// 将ByteData 转成 Uint8List/// [data] ByteData数据/// return [Uint8List] Uint8Liststatic byteData2Uint8List(ByteData data) {return data.buffer.asUint8List();}

Flutter 学习 之 图片的选择、裁切、保存相关推荐

  1. flutter学习(3)图片组件

    flutter学习(3)图片组件 文章目录 flutter学习(3)图片组件 一.远程图片 二.Flutter实现圆角以及实现圆形图片 法一 法二(较简单) 三.本地图片 1.新建目录结构 2.修改p ...

  2. Flutter学习笔记(10)--容器组件、图片组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 上一篇Flutter学习笔记(9)--组件Widget我们说到了在Flutter中一个非常重要的理念"一切皆为组件 ...

  3. #OpenCV学习之图片读取,显示, 色彩空间变化,保存

    函数: nameWindow.imread.imshow.imwrite nameWindow void namedWindow(const String& winname, int flag ...

  4. flutter scrollview_简单易上手的Flutter学习指南App,2020一起来玩转Flutter吧~

    Flutter是谷歌的移动UI框架,可以快速在iOS.Android.Web和PC上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的开发者和 ...

  5. Flutter 学习

    Flutter 学习 参照:https://book.flutterchina.club/ 参照:https://flutter.cn/docs/development/platform-integr ...

  6. Flutter学习之入门和体验

    作者:真丶深红骑士 链接: https://juejin.im/user/597247ad5188255aed1fbba6 本文由作者授权发布. 01前言 1.什么是Flutter 上周我的一位微信好 ...

  7. Flutter学习-基础Widget

    Flutter学习-基础Widget 1. Flutter编程范式 1.1 编程范式的理解 1.2 flutter的编程范式 2. Text Widget 2.1 普通文本展示 2.2 富文本 2.3 ...

  8. Flutter学习笔记学习资料推荐

    对Flutter的学习已经有一段时间了,这里做一下总结记录,东西比较多,可能主要是一些学习资料的记录,还有一些杂七杂八的学习笔记. 文章目录 Flutter 初体验 Flutter 环境配置 Flut ...

  9. iOS程序猿的flutter学习之路

    日常学习Flutter开发的积累 推荐一些平时自己学习Flutter开发当中接触到的优秀文章 -------------------------基础知识 ----------------------- ...

最新文章

  1. SharePoint Server 2013 之四:部署SharePoint企业版
  2. 算法训练 区间k大数查询
  3. [Selenium]Eclipse hangs at 57% in debug mode with TestNG tests
  4. linux服务器centos系统apache路径不区分大小写的解决办法(适用WDCP面板)
  5. Android --- 解决 cannot connect to daemon at tcp:5037: cannot connect to 127.0.0.1:5037: 由于目标计算机积极拒绝,无
  6. android 自动补全方法,Android零基础入门|自动完成文本框AutoCompleteTextView
  7. platform_set_drvdata和platform_get_drvdata用法【转】
  8. html5 输入用户名和密码登陆网址,192.168.5.1路由器登录入口用户名和密码
  9. python/sklearn 生成分类、回归的数据
  10. (36)FPGA面试题D触发器实现4进制计数器
  11. 风投盯上阿里云开发者大会寻下一个阿里
  12. CnOpenData国际货物贸易数据
  13. 2022年后人工智能八大应用方向
  14. iOS开发:Mach-O入门理解
  15. 【IOI2000】 邮局
  16. Spring in Action:@Vaild 表单验证不起作用
  17. linux永久修改dns
  18. Golang postgres.go:45:3: unknown field ‘WithReturning‘ in struct literal of type....
  19. Daemon函数的用法
  20. 用python制作田字格_2分钟学会在Word中制作田字格 米字格 书法练字再也不用买本子了...

热门文章

  1. c语言数组几个数求次大值
  2. 井底看世界----物联网之蓝牙mesh、NB-IOT、RISC-V
  3. 开源里程碑 | 数据应用开发管理集成框架 DataSphere Studio 1.1.0 新版本发布
  4. 系统--电脑开机一声长响
  5. Windows删除文件时出现,“正在准备 再循环”
  6. ajax获取复选框选中的值,获取checkbox中被选中的值
  7. Python MySQL数据库的连接以及基本操作
  8. 出来混一定要懂得人情世故
  9. 苹果5s现在还能用吗_钉子户的iPhone6s,是靠什么挺到现在?2020年了还会继续用吗?|iphone6s|苹果手机|魅族|手机|智能手机...
  10. 南方人物周刊:雷军的宿命