我们知道,理想的网页应该在 1 秒内打开,而在页面的整体大小中,图片往往是所占比例最大的一部分(大约占到 60% 以上,更多了解请点击),也可以参照如下图所示。优化图片不仅可以加快页面显示,还能降低移动网络的流量费用。原图产生的 PNG、JPEG、GIF 和 SVG 图片一般都有很大的压缩余地。下文将重点介绍一款图片新格式:WebP,从而揭开它神秘的面纱。
解决方案:使用 WebP 优化图像
WebP是一种同时提供了有损压缩与无损压缩(可逆压缩)的图片文件格式,至于什么是有损压缩,什么是无损压缩,自己点进去看看
与JPG相同的时,WebP也采用宏块进行压缩,典型的宏块由一个 16×16 的亮度像素(luma pixel)块和两个 8×8 的色度像素(chroma pixel)块组成。分块越小,预测越准,需要记录的信息也越多,一版来说,细节月丰富的地方,分块越细。相对不丰富的地方使用16x16分块。
image.png
WebP最大的不同之处在于每个4x4的宏块中都有一个预测模型。(又名:过滤),PNG过滤用的比较多,它对每一行做同样的事,WebP过滤是针对每一个块。
VP8帧内预测常用的三种宏块:
编码器会将它们放在一个4x4的测试像素块填满,并确定哪一个生成了最接近原始块的值。这些用不同方法填满的块叫做”预测块”。
主要使用的预测方式有以下4种:
image.png
对于4x4的亮度块,会有6种额外预测模式,类似于垂直预测与水平预测方式,他们可以从不同的方向去填充剩余色块。
将预测部分的原图数据减去预测出来的数据,得到差值矩阵,最后对差值进行DCT。此步骤会生成一个频率系数矩阵,坐上的系数幅度最大,右下的最小,幅度值越小,频率越高。大部分图片信息都在左上区域,这一步的作用就是朱熬出图片的高频区域和低频区域。
人眼对高频部分不敏感,这一步会将高频部分舍去。对上一步的频率系数表和量化表进行计算,将频率系数表和量化表按位相除,并四舍五入整数位,最终生成一个量化矩阵。
WebP不同于JPEG,也可以说由于JPEG压缩的地方在于,WebP采用了算法编码压缩(Arithmetic encoding),JPEG采用的是霍夫曼编码(Huffman encoding),算法编码提供了优于霍夫曼编码5%-10%的压缩率。
Android 系统在 4.0 版本中添加入了 WebP 的支持,并在 4.2.1 版本中加强了它:
Fresco 默认使用系统的 WebP 方案来加载它。
但同时,Fresco 能够让你在更老的版本中使用 WebP,所以如果你想要在 Android 2.3 版本的设备上使用 WebP, 你需要做的就是在工程中添加一个 webpsupport的依赖:
dependencies { // your App's other dependencies compile 'com.facebook.fresco:webpsupport:1.0.1'}
实践出真知,为了得出准确的结论,将WebP技术应用到我们的58Android项目中,以下内容都为实践结论:
将PNG转换WebP的效果
将三种图片同时在手机上显示查看效果,图片类型如下:
从上图可以看出三种图片从肉眼看是无差别的
PNG转WebP是可以控制有损压缩比例的,上图有损压缩75%,肉眼查看无差别,那其他的压缩比例呢?
接下来我们继续做实验查看:
三张图片进行对比
第一张为原图、第二张为使用tinypng在线压缩过的图片、第三张为WebP不同压缩比例的图片
通过图片效果对比和上表数据分析,WebP的有损压缩75%是图片肉眼看是无差别的,文件体积减少也是较大的,是官方推荐方案
以上对比我们初步有了方案,再思考一个问题:
PNG经(tinypng)压缩是可以叠加压缩,同时图片体积也叠加减少的,那叠加压缩的图片在进行WebP转换是不是效果会更好呢?
带着问题我们做一个实验
原图转换WebP
第一次压缩(叠加)后转换WebP
第二次压缩(叠加)后转换WebP
第三次压缩(叠加)后转换WebP
第四次压缩(叠加)后转换WebP
可以看出图片肉眼看是无差别的
我们在分析一下体积变化
结论:webp文体大小与图片压缩次数成正比,WebP的转换最好是用原图转换
GIF转换WebP效果对比
PNG(images with transparency/alpha)转换WebP效果对比
带有透明通道的图片转换效果对比
查看效果后产出结论
1、项目中的原图体积是39.6KB(之前是经过压缩了的图片),转换(75%)后的体积是43.0KB,反而增大了;2、不是所有的图片在推荐的有损转换75%的情况下体积会变小,尤其是有透明度通道的图片; 四、讲解一下Android studio 自带 WebP Tool
以上试验可以看到WebP转换技术可以使图片体积减小,如果我们将项目中的资源图片都替换成WebP是不是APK的体积会明显减小呢?
就以我们58主工程的hybrid module的drawable资源做实验
效果分析:1、仅hybird库就可以减少将近1MB的大小,全部替换更客观; 2、但因为WebP格式存在机型适配问题,不能将全部图片替换.
WebP对图片的体积减少真的是个利器,那么内存方面的影响呢,我们项目中图片框架是Fresco,同时Fresco对WebP也做了很好的支持,接下来使用Fresco加载WebP查看内存的占用。
项目中往往引导图都是较大的图片资源,使用引导图作为试验对象,查看内存情况,同时可以得出是否有优化空间。
1、项目中找一个引导图做实践
先来看PNG和WebP图片引导图的显示效果
PNG图片,原生控件ImageView加载显示
WebP图片,Fresco控件加载WebP显示
显示效果一致,肉眼看无差别 #引导图PNG转换为WebP操作数据对比
图片体积减少40% 2、引导图PNG和WebP内存占用对比
为了更好的显示对比效果,我做了一个显示数量扩大的试验,具体操作步骤如下:
先使用PNG图片为引导图
将PNG图片转换为WebP后使用Fresco加载,重复PNG图片引导图的操作步骤,然后进行数据对比
3、将结果纪录并对比
结论:1、5.0以上系统,由于内存管理的优化,所以对于5.0以上的系统 Fresco将Bitmap缓存直接放到了JAVA Heap中,5.0以下系统,图片不存储在Java heap,而是存储在ashmem;2、Android 原生ImageView的PNG显示引导图增大了native heap内存;3、使用原生ImageView 加载图片内存增大要比使用Fresco大;4、强制执行GC只会释放Java Heap,对Native Heap 无影响; 七、Android Profier的使用简介
如上图所示,内存分析器的默认视图包括以下内容:
在classes列表中,您可以看到以下信息:
在类列表的顶部,可以使用左下拉列表在以下堆转储之间切换
WebP的压缩优于其他图片,主要得益于起继承自VP8的帧内预测技术,相比于JPEG对图像原值进行编码来说,WebP编码的是预测值和原值的差值,这也是WebP体积更小的主要原因,最后,WebP使用了更优秀的算法编码。有关Android性能优化的更多学习;可前往:
当然以上主要是针对WebP的有损压缩(lossy WebP)来进行的原理讲解,无损压缩的逻辑与其完全不同,不过我们提高性能,主要也是采用的有损WebP。
希望以上内容,对大家了解WebP的原理有一定的帮助,能让大家更好的去使用WebP。