接着上面图像编码格式学习,今天我们来了解一下WebP格式。

WebP介绍
WebP 是一种由 Google 开发的图像格式,旨在提供比传统 PNG 和 JPEG 格式更高效的压缩算法。它可以在保持很好的视觉质量的同时减小文件大小,从而加快图像加载速度并降低带宽成本。
相较于 PNG 和 JPEG 格式,WebP 具有以下特点:
  • 更高的压缩率:WebP 使用了先进的压缩算法,可以将文件大小减少 25% 至 34%,同时保持与原始图像相同的视觉质量
  • 更快的加载速度:由于文件大小更小,因此加载速度更快,可以提高用户体验。
  • 支持透明度:WebP 支持 alpha 通道,使其能够处理透明度和半透明效果。
  • 更广泛的浏览器支持:现代浏览器几乎都支持 WebP 格式,如 Chrome、Firefox、Edge 等。
虽然 WebP 的优点显而易见,但仍存在一些限制,例如:
  • 兼容性问题:某些老版本的浏览器不支持 WebP 格式,这可能会导致一些用户无法查看图像。
  • 编辑:WebP 目前并没有像 Photoshop 那样完善的编辑工具支持。
  • 可移植性问题:一些应用程序和设备可能不支持 WebP 格式。
WebP发展历程
WebP 是由 Google 公司发起的一个图像压缩格式项目,其发展历程如下:
WebP特点
WebP 是在移动互联网时代产生的一种图像压缩格式。由于移动设备的普及,越来越多的用户开始使用手机和平板电脑浏览网页,而这些设备通常具有较小的屏幕和较慢的网络连接速度。为了提高网站性能和用户体验,需要采用更高效的图像压缩算法。
WebP 正是为了满足这个需求而产生的一个图像压缩格式项目,旨在提供比传统 PNG 和 JPEG 格式更高效的压缩算法。其能够在保持很好的视觉质量的同时减小文件大小,从而加快图像加载速度并降低带宽成本,特别适合在移动设备上显示。
  • 图片文件大小过大:传统的图片格式(如 JPEG 和 PNG)在保证图像质量的前提下,文件大小较大,这会导致图片加载速度变慢,网站性能也受到一定影响。WebP 使用了先进的压缩算法,可以将文件大小减少 25% 至 34%,从而提高了图片加载速度和网站性能。
  • 移动设备访问速度慢:对于移动设备用户来说,网速通常比桌面用户更慢,因此他们需要等待更长的时间才能查看页面中的图片。WebP 压缩后的文件大小更小,移动设备可以更快地获取并显示这些图像。
  • 网站带宽成本高:如果一个网站有很多图片,那么这些图片的传输所占用的带宽是相当大的。WebP 可以将文件大小降低,从而减少网站的带宽成本。
  • 动态效果展示不方便:传统的 GIF 格式虽然支持动态效果,但其文件大小较大,且只支持调色板的颜色数目较少,不能很好地呈现真实的颜色。WebP 支持对多个帧的压缩和处理,可以将多帧图像压缩成一个 WebP 动画文件,从而解决了这个问题。
webp核心技术
WebP 是一种基于 VP8 视频编码技术的图像格式,编码框架如下:
其核心步骤如下:
(1)预处理:在开始压缩之前,WebP 图像首先经过预处理阶段。这包括噪音消除、去块等图像优化步骤,以改善编码效率。
(2)色彩转换:输入图像从 RGB 转换为 YUV 色彩空间。YUV 色彩模型将颜色信息分为亮度(Y)、色度(U)和饱和度(V)分量,有助于更高效地压缩图像。
(3)块预测:WebP 利用块预测来减少冗余数据。对于无损编码,它使用像素值之间的差异进行编码;对于有损编码,它使用VP8块预测编码方法来估计当前块中每个像素的值。
(4)变换编码:在有损编码情况下,WebP 使用 DCT(离散余弦变换)对图像块进行频域转换。这有助于聚集图像中的低频信息,并允许有效地量化和压缩高频部分。
(5)量化:量化进一步压缩图像数据。在WebP有损编码中采用块编码模式对于低熵段,减少位;对于高熵段,采用高位,以减少数据大小。这将导致一些图像细节的损失,但可以显著降低文件大小。
(6)熵编码:压缩后的数据经过算术熵编码,以便更高效地存储和传输。这一步通过消除数据中的冗余信息进一步减小文件大小。
(7)封装:最后,WebP 会将所有压缩数据打包成一个容器格式(Riff 容器),生成最终的 WebP 图像文件。
WebP开源库
Libwebp 是一个开源的图片压缩和格式转换库,用于处理图像数据。它使用了 Google 所开发的 WebP 图像格式,可以让你创建、读取和写入这种类型的图片文件。
libwebp 库提供了 C 和 C++ 接口,可以集成到各种编程语言中。它不仅支持 WebP 格式的图片读写,还支持将其他格式的图片转换为 WebP 格式。此外,libwebp 还提供了一些高级功能,如动态图像编解码、透明度支持等。
参考文献中有非常详尽的文档说明和API说明,可以帮助大家更深入的理解WebP格式。例如编码接口:
size_t WebPEncodeRGB(constuint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);size_t WebPEncodeBGR(constuint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output);size_t WebPEncodeRGBA(constuint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output);size_t WebPEncodeBGRA(constuint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output);
解码接口:
uint8_t* WebPDecodeRGBA(constuint8_t* data, size_t data_size, int* width, int* height);uint8_t* WebPDecodeARGB(constuint8_t* data, size_t data_size, int* width, int* height);uint8_t* WebPDecodeBGRA(constuint8_t* data, size_t data_size, int* width, int* height);uint8_t* WebPDecodeRGB(constuint8_t* data, size_t data_size, int* width, int* height);uint8_t* WebPDecodeBGR(constuint8_t* data, size_t data_size, int* width, int* height);
参考文献
https://developers.google.com/speed/webp?hl=zh-cn
https://developers.google.com/speed/webp/docs/api?hl=zh-cn
以上是本文的基本内容,希望对有需要的小伙伴有所帮助。
我是一枚爱跑步的程序猿,维护公众号和知乎专栏《MediaStack》,有兴趣可以关注,一起学习音视频知识,时不时分享实战经验。
继续阅读
阅读原文