在日常的工作、学习中,我们接触最多的图片格式可能就是 JPEG、PNG 了,偶尔可能还会遇到动图 GIF 文件格式。
首先来了解下 JPEG 和 PNG 有什么区别?
-
JEPG 属于有损压缩,不支持透明通道,色彩深度最高支持 24 位。它的压缩机制是通过丢弃人眼不敏感的高频细节来实现的,可以调节压缩率。比较适合照片、风景图、人物肖像等色彩过渡丰富的场景,能以较小的体积还原真实色彩。
-
PNG 属于无损压缩,可以保留所有原始数据,支持 alpha 透明通道。它的压缩机制是仅去除数据冗余,不会丢失图像信息。PNG 支持更高的 48 位色彩深度,适合高精度图像、医学影像、设计原稿等对色彩还原度要求极高的场景。
虽说这些文件格式能够覆盖绝大部分场景,兼容性也好,但是也有它不足的地方。比如电商平台的网页需要展示大量的图片资源,就会导致网页加载的速度特别慢。
Google 近些年一直在寻找各种方法来加载网页的加载速度,其中一种方法就是减小网页图片的大小。因为在多数网页上,图片占内存字节数的比例最高可达 60~65%,而网页大小是总渲染时间的主要因素。
图片大小对移动设备上也是非常的重要,因为在移动设备上,展示的图片资源越小,所消耗的流量也就越少,电池的续航时间也会越长。
WebP 是由 Google 在 2010 年推出的一种现代图像格式,它的目标是:在保持相同画质的前提下,让图片文件的体积变得更小。
那么 WebP 有哪些核心卖点呢?
1、极致的压缩率 📉 这也是 WebP 的核心卖点。该格式经过优化,可让网页上的图片更小、加载更快。与 PNG 和 JPEG 图片相比,在视觉效果相当的情况下,WebP 图片的大小大约会缩小 30%。
2、全场景范围支持 🛠️ 以前我们选择图片的时候可能还会考虑下到底使用什么图片格式,现在不用了,WebP 不仅可以更好的压缩图片,并且几乎支持世面上其他图片格式的所有功能,因此它是大多数图片格式的绝佳替代方案。
另外,它还支持带透明度的有损图片,如果将透明的 PNG 替换成有损的 alpha WebP 可平均缩减 60~70% 的大小!
你可以把它看作是图片界的“压缩大师”,它集各家之长于一身,试图一统江湖。
WebP 凭什么碾压 JPEG 和 PNG ?
在这里,我们主要了解下 WebP 分别在有损压缩和无损压缩上做了哪些优化。这一章节主要讲述了 WebP 所用到的压缩技术原理,不感兴趣的话可以直接划到下一章节。
先来看看有损压缩。
WebP 有损压缩技术基于 VP8 关键帧编码,VP8 是由 On2 Technologies 创建的视频压缩格式,后来 On2 Technologies 被 Google 所收购,应用于 WebRTC 项目中。
WebP 的无损压缩使用与 VP8 相同的方法来预测(视频)帧。VP8 基于块预测,与任何基于块的编解码器一样,VP8 会将帧划分为称为宏块的较小片段。
在每个宏块中,编码器可以根据之前处理的块预测冗余的运动和颜色信息。图像帧是“关键”帧,因为它仅使用每个宏块的直接空间邻域中已解码的像素,并尝试填充其未知部分,这称为预测编码。
然后,系统可以从块中减去冗余数据,从而提高压缩效率。我们只剩下一个小差异(称为残差),需要以压缩形式传输。
经过数学可逆转换(著名的 DCT,即离散余弦转换)后,残差通常包含许多零值,这些值可以更有效地压缩。然后,系统会对结果进行量化和熵编码。
下图展示了 WebP 有损压缩所涉及的步骤。与 JPEG 相比的差异化功能用红色圈出。
WebP 使用块量化,并在不同的图片片段中自适应分配位数:低熵片段使用较少的位数,高熵片段使用较多的位数。WebP 使用算术熵编码,与 JPEG 中使用的 Huffman 编码相比,可实现更好的压缩效果。
为了提高图片质量,系统会将图片分割成具有明显相似特征的区域。对于这些片段中的每一个,压缩参数(量化步骤、滤波强度等)都会单独进行调整。这样可以将位重新分配到最有用的位置,从而实现高效压缩。
预测编码是 WebP 胜过 JPEG 的主要原因,块自适应量化也有很大影响。过滤功能在中/低比特率下有用。与 Huffman 编码相比,布尔算术编码可实现 5%-10% 的压缩增益。
再来看看 WebP 的无损压缩。
WebP 的无损压缩是 WebP 团队自研的,WebP 无损编码基于使用多种不同的技术来转换图片。然后,对转换参数和转换后的图片数据执行熵编码。
应用于图片的转换包括像素的空间预测、颜色空间转换、使用本地出现的调色板、将多个像素打包到一个像素中,以及 Alpha 替换。
对于熵编码,WebP 团队使用 LZ77-Huffman 编码的变体,该变体使用距离值和紧凑稀疏值的二维编码。
1、预测器(空间)转换
空间预测利用相邻像素之间通常存在关联这一事实来减少熵。在预测器转换中,当前像素值是根据已解码的像素(按扫描线顺序)预测得出的,并且仅编码残差值(实际值 - 预测值)。预测模式决定了要使用的预测类型。图片被划分为多个方形区域,一个方形中的所有像素都使用相同的预测模式。
有 13 种不同的可能预测模式。主要像素是左侧、顶部、左上角和右上角像素。其余的颜色是左侧、顶部、左上角和右上角的组合(平均值)。
2、颜色(去相关)转换
颜色转换的目标是解除每个像素的 R、G 和 B 值之间的相关性。颜色转换会保持绿色 (G) 值不变,根据绿色转换红色 (R),然后根据绿色和红色转换蓝色 (B)。
与预测器转换一样,首先将图片划分为多个块,并对块中的所有像素使用相同的转换模式。对于每个分块,有三种类型的颜色转换元素:green_to_red、green_to_blue 和 red_to_blue。
3、减去绿色转换
“减去绿色转换”会从每个像素的红色和蓝色值中减去绿色值。存在此转换时,解码器需要将绿色值添加到红色和蓝色中。这是上述一般色彩去相关性转换的一个特例,其频率足以保证截断。
4、颜色索引(palette)转换
如果不存在太多唯一的像素值,创建颜色索引数组并将像素值替换为数组的索引,可能会更高效。颜色编号转换可实现这一点。颜色编制转换会检查图片中唯一 ARGB 值的数量。如果该数量低于阈值 (256),则会创建这些 ARGB 值的数组,然后使用该数组将像素值替换为相应的索引。
5、颜色缓存编码
无损 WebP 压缩会使用已见的图片碎片来重构新的像素。如果未找到任何匹配项,它还可以使用本地调色板。此调色板会持续更新,以重复使用近期的颜色。
在下图中,您可以看到本地颜色缓存在扫描向下进行时,会逐步更新为最近使用的 32 种颜色。
6、LZ77 向后引用
向后引用是长度和距离代码的元组。长度表示要按扫描线顺序复制的像素数。距离代码是一个数字,表示之前看到的像素的位置,系统会从该位置复制像素。长度和距离值使用 LZ77 前缀编码进行存储。
LZ77 前缀编码将大整数值分为两部分:前缀代码和额外位。前缀代码使用熵代码存储,而额外的位则按原样存储(不使用熵代码)。
下图展示了使用字词匹配(而非像素)的 LZ77(2D 变体)。
哪些场景更适合使用 WebP 呢?
既然 WebP 这么强,是不是所有地方都该用?答案是:几乎是! 尤其是以下场景:
1、移动端网页和 App,因为移动端设备网络可能有些存在一些不稳定的情况。使用 WebP 可以显著的减少图片数据传输量,让用户在弱网环境下也能有比较好的体验。
另外,手机 App 预置的图片换成 WebP 可以明显减少包体积,在 App 运行阶段也可以减少不少的内存,干过开发的都知道,移动端应用的内存杀手就是图片资源。应用程序运行内存阈值降低,也会有效减小线上的崩溃率。
2、电商和资讯类网站,这类网站图片比较密集,比如说商品图、Banner 之类的。把这些图片换成 WebP,首页加载速度绝对能够提升一个档次,用户体验直接起飞,用户留存率也会随之提高。
3、需要透明背景的复杂图片,之前为了透明背景只能选择 PNG,导致文件相对来说大了不少,前面刚说过,PNG 是无损压缩的。
现在可以使用 WebP 了,不仅可以保留透明效果,Google 针对这种场景把图片压缩到比使用 PNG 体积平均缩减 60~70%。
4、表情包和动图素材,WebP 动图比 GIF 占用资源更小,解码更高效。以前传统的 GIF 动画一个简单的效果动辄就要 800 KB,使用 WebP 仅需 300 KB 左右,并且还支持 24 位色彩深度和透明通道。
据说 B 站将弹幕表情转为 WebP 后,动图加载速度提升了 3 倍。
WebP 的 “阿喀琉斯之踵”!
既然 WebP 这么强大,那么为什么至今还没有彻底的消灭 JPEG 和 PNG 呢?因为它也有自己的 “阿喀琉斯之踵”。
阿喀琉斯之踵是一个源自希腊神话的典故,现在常用来比喻一个人或事物最致命的弱点或缺陷。
阿喀琉斯是希腊神话中的半神英雄,他的母亲忒提斯为了让他刀枪不入,在他幼年时将他浸入冥河斯堤克斯的水中。但母亲握住他的脚踝(脚后跟)没有沾到冥河水,这就成了他全身唯一的弱点。 在特洛伊战争中,阿喀琉斯战无不胜,却最终被敌人一箭射中脚踝而身亡。
我们从上文知道,WebP 的压缩比能够比 JPEG/PNG 做到更低的原因是因为,它的压缩原理比传统的更复杂,这势必会付出一些额外的一些转化的代价。
还是看场景,如果是你自己搭建个人博客的话,这些因素当然都无关紧要。但是如果一个大的电商平台,需要实时处理海量用户上传的图片资源,将它们批量转化为 WebP 格式,肯定会给服务器 CPU 带来一定的压力。
一般的,这类公司可能会使用到 CDN 节点来辅助做这些事情。
还有从体验上来说,JPEG 在加载的时候可以做到 "先模糊、后清晰" 的这种 “渐进式” 体验,而 WebP 不支持这种加载方式。
在网速不好的时候,WebP 图片通常是 “块式填充” 从上到下逐行显示,或者一片空白直到加载完成。
为什么会这样呢?因为 JPEG 可以把图片数据按照按频率分层存储,在加载第一帧的时候,只传输图片数据的 “低频信息” (轮廓,大色块),图片此时呈现模糊态。
后续帧会逐步传输 “高频信息” (包括细节、纹理等),图片从模糊逐渐细化到清晰。整个过程是自然的 “渐进式” 加载,无需额外的代码,系统就能渲染出这种效果来。
而 WebP 的 “渐进加载” 的加载逻辑是按 “块” 分块传输的。WebP 和 JEPG 加载方式不同主要源自他们各自的编码原理以及数据组织方式不同,这也决定了系统如何 “渐进式” 来渲染图片。
而这些体验在网络不好的时候,会有比较明显的差异。
最后,在兼容性上来说,WebP 肯定是没有 JPEG 和 PNG 好的,这也比较好理解,毕竟新的技术都需要时间来让生态来逐步的接纳。
目前来说,WebP 在 Google 自家的 Web、安卓生态兼容性是比较好的,比较老的 Windows 或 macOS 系统预览工具可能打不开这类文件。
这时候就需要借助其他三方的工具或者软件来编辑它了,可能在团队协作上面带来一些额外的工作。
本文完,如果觉得不错对你有所帮助,随手点个赞、在看、转发三连吧。谢谢你看我的文章,下次再见。