Android 一整套图片解决方案

4,951 阅读5分钟
原文链接: mp.weixin.qq.com

本文由hss01248投稿。

hss01248的博客地址:

http://blog.csdn.net/hss01248

作者之前分享了Fresco图片加载框架使用经验,本篇为对Android图片一整套解决方案的分享,大家可以留言讨论,也可以推荐一些自己项目中使用的开源库。


1

apk内部图片优化:控制apk大小

几种图片的主要特点:

webp:文件最小,有透明通道。jpg:文件较小,无透明通道。png:文件较大,有透明通道。

对于小图标:

  1. 小图标大多是不规则形状,显示时多会要求能看到后方背景,所以需要有透明通道,一般使用png。尺寸小,没必要转webp。如果图标后方背景为纯色且确定,那么直接用jpg就可以了。

  2. UI给的png图应当再通过tinypng或者“智图”将图标文件大小缩小一些再放入drawable文件夹中。

大图,背景图,默认图:

上传到“智图”,转成webp。

ui设计图尺寸和切图:如何只切一套图就够用?

  1. 查友盟统计数据知道,市场主流屏幕为720p和1080p。

  2. ui按1080p的尺寸来做设计图,在此基础上切一套图,放于xxhdpi下即可适配大多数屏幕了。

一些规则的图案,能用shape画就没必要切图。

2

图片选择和裁剪

裁剪:

系统的图片裁剪被被各家厂商改得面目全非.试用了github的几家,发现ucrop是比较好的,基于此封装了一下:CropUtils(https://github.com/glassLake/CropUtils)

头像的裁剪效果:

查看图片

多图选择:

系统内置的图片选择只支持选单图,于是很多人做出了多图选择的框架,但很多做得不纯粹,又有图片选择又有裁剪的,这个只做图片选择.

基于photoPicker修改了一下ui,做得类似微信,非常流畅:

PhotoPicker(https://github.com/glassLake/PhotoPicker)

查看图片

3

图片上传

上传前根据期望的最终的显示大小进行压缩:压缩算法可参考:luban(https://github.com/Curzibn/Luban)

为了便于拉取图片前就知道图片尺寸,上传所指定的图片路径中需带图片尺寸信息,比如 www.xxyy.com\landscape\jsjidsj-w-h-1080-1920.jpg.

4

服务器端的图片处理api-七牛

服务器端要能够根据图片路径后方拼接的参数对图片进行处理后返回.

最常用的处理方式是:对原图缩小和裁剪,以及图片格式转换.

缩小和裁剪:

比如,请求上面那张图片作为头像,头像组件的大小是80x80像素,那么可以:

www.xxyy.com\landscape\jsjidsj-w-h-1080-1920.jpg?imageMogr2/thumbnail/!80x80r/crop/80x80/

操作的意义是:限定短边,生成不小于80x80的缩略图:这时,会生成短边为80,长边为80*1920/1080.

然后,裁剪成80*80的图.(默认居中裁剪)

格式转换: 如果是用于动态更换的图标,那么保持原来的png格式.如果图片只用于展示,无需透明度,那么转换成jpg.

gif图片:七牛能够对gif图片进行缩略和剪切,也能转成jpg格式。

通过这两步步操作,能够将网络传输的流量最小化.省七牛的流量费,省用户的流量和加载时间.

封装的工具类:github地址(https://github.com/glassLake/ServerPicUtils)

5

客户端:fresco

三级缓存框架内部已经实现,无需赘言.

其具体的使用技巧见博客:

Fresco图片加载框架的介绍,相关开源库以及工具类的封装

通过downsampling + resizing 来最大化减少bitmap占用的内存

框架初始化时设置downsampling为true,就开启了downsampling.

构建图片请求时,传入目标宽高,构建Resization:

ImageRequestBuilder.newBuilderWithSource(uri)
  .setPostprocessor(processor)
  .setResizeOptions(new ResizeOptions(width,height))

最终能达到的效果是,不论是png,jpg,webp,都能按照指定的宽高来向下采样生成该指定宽高bitmap.如果没有指定ResizeOptions,那么生成的bitmap宽高就是图片文件本身的宽高.

注意两者必须配合使用,如果没有设置downsampling为true,则resizing只对jpg生效.

bitmap解码设置成RGB565,以减小内存占用

也是初始化时设置:

ImagePipelineConfig.newBuilder(context)
  .setBitmapsConfig(Bitmap.Config.RGB_565);

gif图片的处理

编码和显示方法与其他几种常用图片不一样.有几个坑,具体请参考先前的一篇博客:[安卓里的gif图片解决方案:Fresco+gif](http://blog.csdn.net/hss01248/article/details/52155673)

容器view滑动中和停止后请求的暂停和恢复

fresco有相关api支持:

Fresco.getImagePipeline().pause();
Fresco.getImagePipeline().resume();
6

图片常见效果

圆角和圆形

fresco本身就支持,xml或代码里设置即可.注意gif图片的特殊性,需要特殊处理.

高斯模糊

使用开源框架NativeStackBlur(https://github.com/Commit451/NativeStackBlur),能够将一个bitmap高斯模糊后返回

或者采用为fresco封装好的高斯模糊处理器:BlurPostprocessor(https://github.com/wasabeef/fresco-processors)


    掘金是一个高质量的技术社区,从 RxJava 到 React Native,性能优化到优秀开源库,让你不错过 Android 开发的每一个技术干货。长按图片二维码识别或者各大应用市场搜索「掘金」,技术干货尽在掌握中。

    查看图片

    如果你有好的文章想和大家分享,欢迎投稿,直接向我投递文章链接即可。

    欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号:

    查看图片