Flutter 图片库重磅开源(flutter图片下载)

Flutter 图片库重磅开源(flutter图片下载)

作者:新宿

背景

去年,闲鱼技术团队新一代图片库 PowerImage 在经过一系列灰度、问题修复、代码调优后,已全量稳定应用于闲鱼。

相对于上一代 IFImage,PowerImage 经过进一步的演进,适应了更多的业务场景与最新的 flutter 特性,解决了一系列痛点:比如,因为完全抛弃了原生的 ImageCache,在与原生图片混用的场景下,会让一些低频的图片反而占用了缓存;比如,我们在模拟器上无法展示图片;比如我们在相册中,需要在图片库之外再搭建图片通道。

详情可阅读:《Flutter 图片库高燃新登场》

PowerImage相关链接:

(点击文末「阅读原文」,可跳转)

Github:(✅star)

https://github.com/alibaba/power_image

Flutter pub:(✅like)

https://pub.dev/packages/power_image

简介

PowerImage 是一个充分利用 native 原生图片库能力、高扩展性的flutter图片库。我们巧妙地将外接纹理与 ffi 方案组合,以更贴近原生的设计,解决了一系列业务痛点。

能力特点

  • 支持加载 UI.Image 能力。在基于外接纹理的方案中,使用方无法拿到真正的 ui.Image 去使用,这导致图片库在这种特殊的使用场景下无能为力。
  • 支持图片预加载能力。正如原生precacheImage一样。这在某些对图片展示速度要求较高的场景下非常有用。
  • 新增纹理缓存,与原生图片库缓存打通!统一图片缓存,避免原生图片混用带来的内存问题。
  • 支持模拟器。在 flutter-1.23.0-18.1.pre之前的版本,模拟器无法展示 Texture Widget。
  • 完善自定义图片类型通道。解决业务自定义图片获取诉求。
  • 完善的异常捕获与收集。
  • 支持动图。(来自淘特的PR)

Flutter 原生方案

在介绍新方案开始之前,先简单回忆一下 flutter 原生图片方案。

Flutter 图片库重磅开源(flutter图片下载)

原生 Image Widget 先通过 ImageProvider 得到 ImageStream,通过监听它的状态,进行各种状态的展示。比如frameBuilderloadingBuilder,最终在图片加载成功后,会rebuildRawImageRawImage 会通过 RenderImage 来绘制,整个绘制的核心是 ImageInfo 中的 ui.Image

  • Image:负责图片加载的各个状态的展示,如加载中、失败、加载成功展示图片等。
  • ImageProvider:负责 ImageStream 的获取,比如系统内置的 NetworkImage、AssetImage 等。
  • ImageStream:图片资源加载的对象。

在梳理 flutter 原生图片方案之后,我们发现是不是有机会在某个环节将 flutter 图片和 native 以原生的方式打通?

新一代方案

我们巧妙地将 FFi 方案与外接纹理方案组合,解决了一系列业务痛点。

FFI

正如开头说的那些问题,Texture 方案有些做不到的事情,这需要其他方案来互补,这其中核心需要的就是ui.Image。我们把 native 内存地址、长度等信息传递给 flutter 侧,用于生成ui.Image

首先 native 侧先获取必要的参数(以 iOS 为例):

Flutter 图片库重磅开源(flutter图片下载)

dart 侧拿到后

Flutter 图片库重磅开源(flutter图片下载)

我们可以通过 ffi 拿到 native 内存,从而生成 ui.Image。这里有个问题,虽然通过 ffi 能直接获取 native 内存,但是由于 decodeImageFromPixels 会有内存拷贝,在拷贝解码后的图片数据时,内存峰值会更加严重。

这里有两个优化方向:

  1. 解码前的图片数据给 flutter,由 flutter 提供的解码器解码,从而削减内存拷贝峰值;
  2. 与 flutter 官方讨论,尝试从内部减少这次内存拷贝。

FFI 这种方式适合轻度使用、特殊场景使用,支持这种方式可以解决无法获取 ui.Image 的问题,也可以在模拟器上展示图片(flutter <= 1.23.0-18.1.pre),并且图片缓存将完全交给 ImageCache 管理。

Texture

Texture 方案与原生结合有一些难度,这里涉及到没有 ui.Image 只有 textureId。这里有几个问题需要解决:

  1. 问题一:Image Widget 需要 ui.Image 去 build RawImage 从而绘制,这在本文前面的Flutter 原生方案介绍中也提到了;
  2. 问题二:ImageCache 依赖 ImageInfo 中 ui.Image 的宽高进行 cache 大小计算以及缓存前的校验;
  3. 问题三:native 侧 texture 生命周期管理。

分别都有解决方案:

问题一:通过自定义 Image 解决,透出 imageBuilder 来让外部自定义图片 widget

问题二:为 Texture 自定义 ui.Image,如下:

Flutter 图片库重磅开源(flutter图片下载)

这样的话,TextureImage 实际上就是个壳,仅仅用来计算 cache 大小。实际上,ImageCache 计算大小,完全没必要直接接触到 ui.Image,可以直接找 ImageInfo 取,这样的话就没有这个问题了。

问题三:关于 native 侧感知 flutter image 释放时机的问题。

修改的 ImageCache 释放如下(部分代码):

Flutter 图片库重磅开源(flutter图片下载)

整体架构

我们将两种解决方案非常优雅地结合在了一起:

Flutter 图片库重磅开源(flutter图片下载)

我们抽象出了 PowerImageProvider ,对于 external(ffi)、texture,分别生产自己的 ImageInfo 即可。它将通过对 PowerImageLoader 的调用,提供统一的加载与释放能力。

蓝色实线的 ImageExt 即为自定义的 Image Widget,为 texture 方式透出了 imageBuilder。

蓝色虚线 ImageCacheExt 即为 ImageCache 的扩展,仅在 flutter < 2.2.0 版本才需要,它将提供 ImageCache 释放时机的回调。

这次,我们也设计了超强的扩展能力。除了支持网络图、本地图、flutter 资源、native 资源外,我们提供了自定义图片类型的通道,flutter 可以传递任何自定义的参数组合给 native,只要 native 注册对应类型 loader,比如「相册」这种场景,使用方可以自定义 imageType 为 album ,native 使用自己的逻辑进行加载图片。有了这个自定义通道,甚至图片滤镜都可以使用 PowerImage 进行展示刷新。

除了图片类型的扩展,渲染类型也可进行自定义。比如在上面 ffi 中说的,为了降低内存拷贝带来的峰值问题,使用方可以在 flutter 侧进行解码,当然这需要 native 图片库提供解码前的数据。

数据

FFI vs Texture

Flutter 图片库重磅开源(flutter图片下载)

机型:iPhone 11 Pro;图片:300 张网络图;行为:在listView中手动滚动到底部再滚动到顶部;
native Cache:20 maxMemoryCount; flutter Cache:30MB

flutter version 2.5.3; release 模式下

这里有两个现象:

FFI: 186MB波动
Texture:194MB波动

在 2.5.3 版本中,Texture 方案与 FFI,在内存水位上差异不大,内存波动上面与 flutter 1.22 结论相反。

图中棋格图,为打开 checkerboardRasterCacheImages 后所展示,可以看出,ffi方案会缓存整个cell,而texture方案,只有cell中的文字被缓存,RasterCache 会使得 ffi 在流畅度方面会有一定优势。

滚动流畅性分析

Flutter 图片库重磅开源(flutter图片下载)

设备: Android OnePlus 8t,CPU和GPU进行了锁频。
case: GridView每行4张图片,300张图片,从上往下,再从下往上,滑动幅度从500,1000,1500,2000,2500,5轮滑动。重复20次。

方式: for i in {1..20}; do flutter drive –target=test_driver/app.dart –profile; done 跑数据,获取TimeLine数据并分析。

结论:

  • UI thread 耗时 texture 方式最好,PowerImage 略好于 IFImage,FFI方式波动比较大。
  • Raster thread 耗时 PowerImage 好于 IFImage。Origin 原生方式好是因为对图片 resize了,其他方式加载的是原图。

更精简的代码

Flutter 图片库重磅开源(flutter图片下载)

dart 侧代码有较大幅度的减少,这归功于技术方案贴合 flutter 原生设计,我们与原生图片共用较多代码。

FFI 方案补全了外接纹理的不足,遵循原生 Image 的设计规范,不仅让我们享受到 ImageCache 带来的统一管理,也带来了更精简的代码。

单测

Flutter 图片库重磅开源(flutter图片下载)

为了保证核心代码的稳定性,我们有着较为完善的单测,行覆盖率接近95%。

关于开源

我们期待通过社区的力量让 PowerImage 更加完善与强大,也希望 PowerImage 能为大家在工程研发中带来收益。

Issues

关于 issue,我们希望大家在使用 PowerImage 遇到问题与诉求时,积极交流,提出 issue 时尽可能提供详细的信息,以减少沟通成本。在提出 issue 前,请确保已阅读 readme。

Flutter 图片库重磅开源(flutter图片下载)

对于 bug 的 issue,我们自定义了模板(Bug report),可以方便地填一些必要的信息。其他类型则可以选择 Open a blank issue

我们每周会花部分时间统一处理 issues,也期待大家的讨论与 PR。

PR

为了保持 PowerImage 核心功能的稳定性,我们有着完善的单测,行覆盖率达到了 95%(power_image库)。

在提交PR时,请确保所提交的代码被单测覆盖到,并且涉及到的单测代码请同时提交。

Flutter 图片库重磅开源(flutter图片下载)

得益于 Github 的 Actions 能力,我们在主分支 push 代码、对主分支进行 PR 操作时,都会触发 flutter test 任务,只有单测通过才可合入。

未来

开源是 PowerImage 的开始,而不是结束,PowerImage 可做的事情还有很多,有趣而丰富。比如第一个 issue 中描述的 loadingBuilder 如何实现?比如 ffi 方案如何支持动图?再比如Kotlin和Swift···

PowerImage 未来将持续演进,在当前 texture 方案与 ffi 方案共存的情况下,伴随着 flutter 本身的迭代,我们将更倾向于向 ffi 发展,正如在上文的对比中, ffi 方案可以天然享用 raster cache 所带来的流畅度的优势。

PowerImage 也会持续追随 flutter 的脚步,以始终贴合原生的设计理念,不断进步,我们希望更多的同学加入进来,共同成长。

PowerImage相关链接:

GitHub:(✅star)

https://github.com/alibaba/power_image

Flutter pub:(✅like)

https://pub.dev/packages/power_image

关注【阿里巴巴移动技术】,阿里前沿移动干货&实践给你思考!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年10月20日 上午10:46
下一篇 2022年10月20日 上午11:00

相关推荐

  • 管理制度(管理制度模板)

    (一) 党总支目标管理制度 1、为加强党的基层组织建设,做好党建工作,制定党总支年度目标管理制度。 2、每年公司党总支都要制定年度工作目标、工作任务、工作进度,党总支年度工作以此为…

    科研百科 2023年7月26日
    154
  • 健全党建体系(健全党建体系的意义)

    首先健全党组织体系。把创建党组织与创先争优、基层组织建设年活动合起来,全面落实基层党建工作各项任务。切实加强党组织班子队伍建设,发挥党组织领导核心作用。实行网格全覆盖,每月召开一次…

    科研百科 2024年6月23日
    64
  • 科研项目怎么做资产负债表

    科研项目怎么做资产负债表 资产负债表是科研项目中非常重要的一个文件,它是反映项目财务状况的重要工具。那么,科研项目怎么做资产负债表呢?下面,我们将为您解答。 首先,我们需要了解资产…

    科研百科 2024年8月13日
    45
  • 如何做好党建工作(如何做好党建工作心得体会)

    党建工作是我们党的优良传统和永葆先进地位的必要保证。基层党组织是党建工作的基本组成部分,在充分落实各项制度政策、密切联系群众、保障社会稳定等各个方面都起着至关重要的作用。加强思想教…

    科研百科 2023年2月10日
    119
  • 2年党龄能担任乡镇党委委员吗

    2年党龄能担任乡镇党委委员吗? 党龄是党员身份的重要标志,也是党员成长的重要阶段。对于一名基层党员来说,党龄短了可能会感到不足,但过长了也可能会有些问题。一般来说,2年党龄可以作为…

    科研百科 2024年10月14日
    20
  • 河北经贸大学协同办公

    河北经贸大学协同办公:推动校园高效运转 随着现代办公环境的不断改善和数字化办公的普及,协同办公已经成为了现代组织中不可或缺的一部分。在河北经贸大学,协同办公不仅有助于提高办公效率,…

    科研百科 2024年11月9日
    1
  • 协同办公什么意思

    协同办公是指多人或多组织之间的协作和联合工作,旨在提高工作效率、生产力和协作能力。在现代商业和工作环境中,协同办公已经成为一种基本的能力,被广泛应用于各种场景,如会议、报告、项目、…

    科研百科 2025年1月4日
    4
  • 人力资源管理业务

    人力资源管理业务 人力资源管理是组织管理中至关重要的一部分,涉及到组织中员工的招聘、培训、薪酬福利、绩效评估等方面。人力资源管理业务可以帮助组织更好地管理和激励员工,提高员工的工作…

    科研百科 2024年9月16日
    20
  • 划红线 给指引——聚焦首次规范基层党组织党建活动经费(基层党组织党建活动经费管理办法)

    新华社北京9月7日电 题:划红线 给指引——聚焦首次规范基层党组织党建活动经费 新华社“中国网事”记者乌梦达 叶前 日前,财政部、中央直属机关工委、中央国家机关工委联合印发了《中央…

    科研百科 2024年6月24日
    73
  • library电子书下载免费网站

    library电子书下载免费网站: 轻松获取优质电子书的助手 随着数字化时代的到来,电子书成为了人们获取信息和知识的一种更加便捷的方式。而library电子书下载免费网站则成为了人…

    科研百科 2024年11月6日
    3