结论先行:

  • photo_manager库 靠谱,满足相册、图片列表内存的使用
  • cacheWidth、cacheHeight 在Image层次上的满足,如果一个页面内固定几张图,推荐这种
  • width、height,对内存优化无效
    • 会先解析原图,4.2M的图,会暴增到121.9 M,然后再resize降低内存

字多的结论

  • 使用photo_manager库 靠谱,好用,内存测过没问题 (成熟,靠谱,推荐使用)

    • 关键就是自定义 ImageProvider,将图片加载导向native
    • Android端用的Glide库管理,IOS用的原生API
    • 源代码对应下文的 成熟的第三方库处理
  • cacheWidth,cacheHeight 影响图像载入内存大小,可进行resize
    • 内存会显著降低(可用,底层代码后续写,测试具体数据看这个)
    • Anyway,重点不是cacheWidth、cacheHeight,它没有内存管理,也没三级缓存。适用于一个页面周期内 单个图片。相册、图片列表、图片瀑布流是不适合的。
  • width、height 对内存的占用不产生影响
    • 会产生峰值,之后resize掉(resize是哪里操作,后续补充) (当然,这也可以说产生影响。)
    • 不过这个峰值 就够OOM了

版本变更

Flutter做了升级,对cacheWidth、cacheHeight。具体见提交

When down-scaling images, decode encoded images into smaller images
closer to the target size before finally down-scaling them to their
target size. For very large images this can avoid inflating the image
into its full size first before throwing it away. This can help to
significantly reduce peak memory utilization.

内存抓取

测试具体数据看这个

波峰的为使用width、height,较为平稳的是使用cacheWidth、cacheHeight。


图片大小计算

1080P图片大小,RGBA 8888格式每个通道占8bite = 1byte, 4通道图像的1个像素=4byte192010804= 8294400B 8294400/1024/1024 = 7.9101MB所以,1080P的图片在内存中占用不到8M.

Android Bitmap OOM native解决方式

报错

E/flutter: [ERROR:flutter/lib/ui/painting/image_descriptor.cc(174)] Failed to allocate memory for bitmap of size 127844352B
E/flutter: [ERROR:flutter/lib/ui/painting/image_decoder.cc(289)] Could not decompress image.

成熟的第三方库处理

  • wechat_assets_picker 库,提供了flutter仿 微信相册的库,主要是UI的搭建。
  • wechat这个库依赖 photo_manager库,来提供 相册数据、加载图片、内存管理。

解决思路:

Flutter Image widget转路径给自定义ImageProvider
ImageProvider根据路径生成 图像byte list
通过桥调用native的实现
Android转给Glide库区加载,轻松解决内存问题。

flutter代码

Image包裹ImageProvider

        return Image(fit: BoxFit.contain,image: AssetEntityImageProvider(asset,isOriginal: widget.previewThumbSize == null,thumbSize: widget.previewThumbSize,));

Provider包裹桥接口

AssetEntityImageProvider extends ImageProvider<AssetEntityImageProvider> {
///...@overrideImageStreamCompleter load(AssetEntityImageProvider key,DecoderCallback decode,) {return MultiFrameImageStreamCompleter(codec: _loadAsync(key, decode),scale: key.scale,informationCollector: () {return <DiagnosticsNode>[DiagnosticsProperty<ImageProvider>('Image provider', this),DiagnosticsProperty<AssetEntityImageProvider>('Image key', key),];},);}
///... _loadAsync 重点Future<ui.Codec> _loadAsync(AssetEntityImageProvider key, DecoderCallback decode) async {assert(key == this);Uint8List data;///...data = await key.entity.thumbDataWithOption(_thumbOption(_thumbSize[0], _thumbSize[1]),);///...

调用photo_mananger里的桥

  /// Get thumb with size of option.Future<Uint8List?> thumbDataWithOption(ThumbOption option, {PMProgressHandler? progressHandler,}) async {assert(() {option.checkAssert();return true;}());/// Return null if asset is audio or other type, because they don't have such a thing.if (type == AssetType.audio || type == AssetType.other) {return null;}return PhotoManager._getThumbDataWithOption(id,option,progressHandler,);}

Android桥对应的代码

关键代码: resultHandler.reply(bos.toByteArray()) 这个byte[] 到Uint8List

    fun getThumbnailByGlide(ctx: Context,path: String,width: Int,height: Int,format: Bitmap.CompressFormat,quality: Int,result: MethodChannel.Result?) {val resultHandler = ResultHandler(result)Glide.with(ctx).load(File(path)).asBitmap().priority(Priority.IMMEDIATE).into(object : BitmapTarget(width, height) {override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>?) {super.onResourceReady(resource, glideAnimation)val bos = ByteArrayOutputStream()resource.compress(format, quality, bos)resultHandler.reply(bos.toByteArray())}override fun onLoadCleared(placeholder: Drawable?) {resultHandler.reply(null)}override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {resultHandler.reply(null)}})}

简单修复方案

FutureBuilder<File>(future: asset.file,builder: (context, snapshot) {if (snapshot != null &&snapshot.data != null &&snapshot.connectionState == ConnectionState.done) {return Image.file(snapshot.data,fit: BoxFit.contain,cacheWidth: ScreenUtil.getScreenWidth(context).toInt(),cacheHeight: ScreenUtil.getScreenHeight(context).toInt(),);} else {return const SizedBox.shrink();}});

Flutter加载大图内存问题处理相关推荐

  1. 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题

    本文转载至 http://www.superqq.com/blog/2015/01/22/jie-jue-mwphotobrowserzhong-de-sdwebimagejia-zai-da-tu- ...

  2. Android高效加载大图、多图解决方案,有效避免程序内存溢出现象

    好久没有写博客了,今天就先写一个小的关于在Android中加载大图如何避免内存溢出的问题. 后面会写如何使用缓存技术的核心类,android.support.v4.util.LruCache来加载图片 ...

  3. 加载大量图片内存暴增导致闪退 Terminated due to memory issue(内存暴增SDWebImage加载高清大图崩溃)

    上传图片一定要压缩,一定要压缩,一定要压缩.(目前手机拍摄的图片一张几M,上传后不压缩,如果几十张一块加载展示时内存画面有点美!如果是后台上传除了需要高清以外的图也需要压缩处理) 下载大量图片时一定要 ...

  4. Android 加载大图的缩略图显示

    问题来了 在android中,我们很多界面都会用到图片显示,我们从网络服务器上加载图片到本地,并显示出来,这个操作我想大家都很熟悉吧? 很多新手,比如我自己,之前从来没有考虑过图片大小问题,一般从服务 ...

  5. android 加载大图 代理,Android 加载大图

    在 Android 开发中, Bitmap 是个吃内存大户,稍微操作不当就会 OOM .虽然现在第三方的图片加载库已经很多,很完善,但是作为一个 Androider 还得知道如何自己进行操作来加载大图 ...

  6. c语言文件 加载内存吗,把文件中的数据加载到内存进行查找C语言实现.docx

    把文件中的数据加载到内存进行查找C语言实现 #define _CRT_SECURE_NO_WARNINGS#include#include#includechar **pp=NULL;void ini ...

  7. Android高效加载大图、多图解决方案,有效避免程序OOM

    高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...

  8. tflearn 数据集太大无法加载进内存问题?——使用image_preloader 或者是 hdf5 dataset to deal with that issue...

    tflearn 数据集太大无法加载进内存问题? Hi, all! I'm trying to train deep net on a big dataset that doesn't fit into ...

  9. 高效地加载图片(一) 高效地加载大图

    1.Read Bitmap Dimensions and Type 读取图片的尺寸和类型 //创建一个Options,用于保存图片的参数 BitmapFactory.Options options = ...

最新文章

  1. vue 编写H5页面在公众号外部获取手机本地坐标经纬度
  2. 树莓派控制多个舵机_树莓派控制SG90舵机
  3. Python全栈之路Day13
  4. 知道这些面试技巧,让你的测试求职少走弯路
  5. TVP5158的多路复用技术
  6. drools 7.x 决策表使用
  7. 郑继明等《数值分析》习题解答
  8. c++中父类子类对象指针相互转换,成员函数调用方式
  9. c++多线程中detach的使用隐患
  10. 谷粒商城--分布式基础篇1
  11. (AS笔记)Android 实现第三方QQ登录——QQ互联
  12. spring启动简析
  13. 腾飞之势,搏击苍穹:网页设计
  14. 微信公众号数据2019_微信公众号榜单排名,2020微信公众号排名
  15. Basemap库绘制地图
  16. 算法初体验之欧几里得算法
  17. 读书的方法摘录——张五常
  18. 找对英语学习方法的第一本书之:标准发音
  19. mysql slow query_Mysql 开启 Slow 慢查询
  20. linux桌面小程序开发日记3(pyqt5+yolov5)

热门文章

  1. 最详细的虚拟机安装教程
  2. 每一个圣人都有一个过去
  3. 2023最新自助下单彩虹云商城系统源码+免授权无后
  4. 全民一起VBA实战篇 专题2 第二回 选择法轻松上手,双循环巧妙排序
  5. 【佩服】超萌女娃穿尿裤扭臀热舞
  6. m基于FPGA的GPS收发系统开发,包括码同步,载波同步,早迟门跟踪环,其中L1采用QPSK,L2采用BPSK
  7. rm -rf是什么意思?
  8. 瑞萨 RA2E1 触摸按键使用例程
  9. 还在期待安卓9.0吗?Android 10.0要来了
  10. 计算机思维培训心得,2020参加计算机培训心得体会精选