QiniuImageLoader

Additional

Language
Java
Version
v1.0.4 (Jul 18, 2018)
Created
Dec 15, 2015
Updated
May 11, 2019
Owner
LAIX Inc. (formerly LingoChamp Inc.) (lingochamp)
Contributors
Jacksgong
echo500
2
Activity
Badge
Generate
Download
Source code
APK file

Commercial

QiniuImageLoader

如何根据七牛的图片加载API进行加更有效、更节流、更简单、更库的图片加载呢?

PS: 如果你不是使用七牛,也不用担心,只要你兼容相关API也可以支持(下文会提到)。

I. 结果

1. 基本库(library):

new QiniuImageLoader(context, url)
        .centerCrop() // 居中裁剪
        .formatWebp() // 请求下载格式为webp
        .sizeR(R.dimen.target_width) // 请求图片按照该尺寸下发图片
        .addOpBlur(40, 20) // 请求图片进行高斯模糊处理(radius=40, sigma=20)
        .addRotate(60) // 请求图片旋转60度
        .createQiniuUrl(); // 生成对应目标url

// 当然,很多时候你想要的仅仅是图片宽度不超过某大小的图片而已
new QiniuImageLoader(context, url)
        .wR(R.dimen.max_width)
        .createQiniuUrl();

2. 基于Picasso的封装工具库(utils-picasso)

使用基本库的过程中,建议参考这个工具库进行有关封装

该库基于库与picasso,进行上层封装,对接基本库和picasso


// 设置全局默认图片占位符,与头像占位符
PicassoLoader.setGlobalPlaceHolder(R.drawable.default_place_holder, R.drawable.default_avatar_place_holder);

/**
 * 设置全局默认com.squareup.picasso.Target供应者
 * 建议用于绑定Activity生命周期,回收网络资源所用(如Activity#onResume时,
 *      根据target区分出其他Activity,并将他们全部暂停)
 */
PicassoLoader.setGlobalTargetProvider(defaultTargetProvider);

PicassoLoader.display7Niu(imageview1, MOCK_DATA_URL)
             .target(target) // 当前图片加载采用特定的Target
             .attach(); // 显示在imageview1上

PicassoLoader.display7Niu(imageview2, MOCK_DATA_URL)
             .centerCrop() // 居中裁剪
             .wR(R.dimen.max_width) // 居中裁剪时,指定任意一边将会保证双边长度都是指定长度
             .addOpBlur(40, 20) // 请求图片进行高斯模糊处理(radius=40, sigma=20)
             .attach(); // 显示在imageview2上

II. 使用

dependencies {
  // 基本库
  implementation 'com.liulishuo.qiniuimageloader:library:1.0.4'
  // 可不引: 基于基本库与picasso做上层封装,可作为案例,也可直接使用
  implementation 'com.liulishuo.qiniuimageloader:utils-picasso:1.0.4'
}

III. 目前已经适配API

如果你使用的不是七牛,只要你的API也是相同的格式,也可以

具体生成,可以参考QiniuImageLoader中的#createQiniuUrl

参考图片高级处理(imageMogr2),目前已支持参数:

  • /auto-orient
  • /thumbnail/<imageSizeGeometry>
  • /gravity/<gravityType>
  • /crop/<imageSizeAndOffsetGeometry>
  • /format/<destinationImageFormat>
  • /blur/<radius>x<sigma>
  • /rotate/<rotateDegree>

IV. 出发点

结合七牛提供的丰富的图片请求api,在客户端层进行封装,实现与上层到下层图片加载库的中间层URL生成的封装。

对于Android应用而言,图片展示在绝大多数的应用上已经是必备的功能,我们的应用也是如此。那么图片加载优化层面就会有一堆点需要考虑,它决定一款应用是否足够轻盈:

  1. 如何开发一款本地的行之有效,性能卓越的图片加载库(优化资源竞争?封装简洁的接口?强大的图片处理功能?),亦或是如何选择开源优秀的图片加载库呢?(picasso?fresco?glide?bala.bala.)
  2. 如何杜绝OOM(565?Activity空壳化?largeHeep?nodpi?独立进程?)
  3. 更深次的优化,本地cache高斯模糊、旋转、缩放后的结果,归类?管理?预加载?用base64直接带了一些缩略图在普通的REST请求中,对于一些小缩略图做法还是挺有效的,减少连接数,减轻了各类硬件资源冗余使用?

其实很多时候,我们在客户端做了很多工作,却忽略了我们完全可以将这些操作放到云端处理,很多结果存在客户端,还不如存在最近的节点上,很多操作在多个客户端上操作,还不如在云端一次性操作,不但为用户节流,而且稳定,节约客户端资源,简单。本库尝试从架构层结合七牛的库进行封装。

该库直接的益处:

  • 简单的接口,在架构层保证全局漏斗模型,可控,做更多的全局安全处理。
  • 通过默认请求图片是webp实现,相同显示效果的图片大小减少30%~70%(相当可观)
  • 通过每次请求都指定需求图片的宽/高/大小(未指定的情况下,默认为屏幕的宽高作为其值),为用户节约流量的同时,本地缓存的图片资源相应减小,整体内存相应降低
  • 所有的操作(高斯模糊、选择、centerCrop、fitXY等)都放到云端一次性处理,减少本地cpu资源占用

V. 说明

1. 默认值

参数 默认值 备注
size/w/h 不超过屏幕宽高 强制请求原图时,最大值为GL10.GL_MAX_TEXTURE_SIZE
mode FIT_XY 见模式说明
format webp 相同显示效果,webp的大小约png的30%~70%,支持格式见支持格式说明
Op 默认不带 默认不带操作

2. 模式说明

就基本库library而言

模式名 url 说明
CenterCrop /1/w/<Width>/h/<Height> 限定缩略图的宽最少为<Width>,高最少为<Height>,进行等比缩放,居中裁剪。转后的缩略图通常恰好是<Width>x<Height> 的大小(有一个边缩放的时候会因为超出矩形框而被裁剪掉多余部分)。如果只指定w参数或只指定 h参数,代表限定为长宽相等的正方图。
FitXY /2/w/<Width>/h/<Height> 限定缩略图的宽最多为<Width>,高最多为<Height>,进行等比缩放,不裁剪。如果只指定w 参数则表示限定宽(长自适应),只指定h 参数则表示限定长(宽自适应)。
ForceOrigin /1/w/<Width>/h/<Height> 强制需要请求原图

3. 支持格式请求

  • webp (默认值)
  • jpg
  • gif
  • png
  • origin

4. 支持操作请求

  • rotate
  • blur

接口方法说明

1. library:

参数方法 说明
w(width:int)/wR(@DimenRes) 指定最大宽度
h(width:int)/hR(@DimenRes) 指定最大高度
size(size:int)/sizeR(@DimenRes) 指定最大宽高
screenW(void) 指定最大宽度为屏幕宽度
halfScreenW(void) 指定最大宽度为屏幕宽度的一半
wTimesN2H(n:float) 高度为宽度的n倍
fitXY(void) 指定为FitXY模式
centerCrop(void) 指定为CenterCrop模式
forceOrigin(void) 请求图片最大宽高为GL10.GL_MAX_TEXTURE_SIZE
formatJpg(void) 请求图片jpg格式
formatOrigin(void) 请求图片原格式
formatPng(void) 请求图片png格式
formatWebp(void) 请求图片webp格式
addOpBlur(radius:int, sigma:int) 请求图片进行高斯模糊处理
addOpRotate(rotateDegree:int) 请求图片进行旋转处理
attach(void) 加载图片到目标ImageView上并清理所有变量(依赖子类配置底层图片加载库后实现attachNoClear(void)

2. utils-picasso

utils-picasso依赖与librarylibarry拥有的所有参数,utils-picasso都有,下面是utils-picasso做上层封装的时候增加的

特有全局配置

// 设置全局的默认占位图,与默认头像的占位图
PicassoLoader.setGlobalPlaceHolder(defaultPlaceHolder:int, defaultAvatarPlaceHolder:int)

// 设置全局默认的Target提供者
PicassoLoader.setGlobalTargetProvider(@Nullable provider:TargetProvider)
增加的参数方法
参数方法 说明
avatar(void) 占位图采用默认头像的占位图
defaultD(defaultDrawable:Drawable)/defaultD(@DrawableRes) 指定占位图
target(target:com.squareup.picasso.Target) 指定picasso的Target
transformation(transformation:com.squareup.picasso.Transformation) 指定Transformation
attachWidthNoClear(void) 使用Picasso加载图片到目标ImageView上,并且不清理存储的各类属性参数
attachCallback(attachCallback:com.squareup.picasso.Callback) 指定picasso的Callback
fetch(void) 下载图片到本地