天天记事 455 / 2022-11-17 20:35:42
WebP由Google在2010年发布,是一种现代图像格式,可为Web上的图像提供出色的无损和有损压缩。使用WebP,网站管理员和Web开发人员可以创建更小,更丰富的图像,从而使Web更快。
与PNG相比,WebP无损(loseless)图像的尺寸要小26%。在同等的SSIM(Structural Similarity Index,结构相似性)质量指数下,WebP有损(lossy)图像比同类JPEG图像小25-34%。
Lossless WebP支持透明性(也称为Alpha通道),而仅增加了22%的字节数。对于可以接受有损RGB压缩的情况,有损WebP还支持透明性,与PNG相比,文件大小通常小3倍。
并且,Google于2014年提出了动态WebP,拓展WebP使其支持动图能力。动态WebP相比GIF支持更丰富的色彩,并且也占用更小空间,更适应移动网络的动图播放。
与PNG相比
对于libpng而言,lossy WebP不仅具有最高质量(转换)而且具有ZopfliPNG(下表1)的PNG压缩密度,其编码(下表2)和解码(下表3)的速度与PNG的速度大致相当。
1000张网络中的PNG,对其进行压缩后,与对应的无损WebP以及有损带透明WebP比较。可见绝大部分图片经过两种WebP压缩后均比PNG要小。
lossless WebP的编码时间较长,是PNG的5倍以上,但解码速度与PNG差不多,甚至很多时候比PNG快。而WebP在编码时占用内存比PNG高25%,解码时比PNG低30%。
动态WebP vs APNG
APNG是一种基于PNG的编码,对动图的编码方式类似于WebP,都是对变化的区域进行编码。虽然理论上单张WebP要比PNG小,但有些整合成动图形式后WebP会比APNG更大:
详见专门的对比demo:http://littlesvr.ca/apng/gif_apng_webp1.html
下表显示了JPEG质量参数Q的三个不同值(50、75和95)的实验结果。质量参数50和95分别表示低比特率和高比特率下的图像压缩。我们还包括了JPEG质量参数75,因为它通常是JPEG图像的推荐质量等级。
与GIF相比
劣势:
其实还是环境支持不够,添加WebP支持到浏览器需要添加较多代码。
详见专门的对比demo:https://isparta.github.io/compare-webp/index_a.html#12
imageMaigck
imageMaigck是一个通用型的图像处理工具,可在服务端及客户端运行使用,并且可以借助nodejs的gm包实现一些脚本服务。其基本使用可见之前整理的文章《ImageMagick和gm》
cwebp,dwebp
cwebp/dwebp的谷歌官方提供的webp转换工具,官方提供了windows/linux/mac 三个系统版本的工具,其介绍和安装可见《Getting cwebp,dwebp,and the WebP Libraries》。cwebp可以将JPEG,PNG或TIFF编码成WebP;
如
cwebp [options] -q quality input.png -o output.webp
其中option可选:
loss(有损压缩,默认)
lossless(无损压缩)
q:质量指数(压缩率),有损压缩有效,无损压缩忽略
o:输入图片名称格式
cwebp [options] input_file -o output_file.webp
其他选项:
dwebp可以将WebP解码成PNG。
如
dwebp iutput.webp -o output.png
webmux也是处理webp的工具,从静态的webp images创建动态的webp,或者从动态的webp提取静态的webp images。以及管理XMP/EXIF数据和ICC描述文件。
语法
其中选型:
-get
选项:GET_OPTIONS-set
选项:SET_OPTIONS-strip
选项:STRIP_OPTIONS-duration
选项:DURATION_OPTIONSduration[,start[,end]]
-frame
选项:FRAME_OPTIONS-loop
n-bgcolor
A,R,G,B<picture> 元素通过包含零或多个 <source> 元素和一个 <img> 元素来为不同的显示/设备场景提供图像版本。浏览器会选择最匹配的子 <source> 元素,如果没有匹配的,就选择 <img> 元素的 src 属性中的URL。然后,所选图像呈现在 <img> 元素占据的空间中。
如:
<picture>
<source srcset="logo.webp" type="image/webp">
<img src="logo.png" alt="Site Logo">
</picture>
一个WebP文件表示一个静态图片或动画,并可选的包含透明度、色彩配置文件和元数据等。WebP使用VP8关键帧编码以有损方式压缩图像数据,或者WebP无损编码(以及将来可能的其他编码)。
WebP容器(即WebP的RIFF容器)允许在WebP基本用例(即,包含编码为VP8关键帧的单个图像的文件)之上的功能支持。 WebP容器为以下内容提供附加支持:
建议在引用WebP容器时使用以下类型:
Container Format Name | WebP |
---|---|
Filename Extension | .webp |
MIME-type | image/webp |
Uniform Type Identifier | org.webmproject.webp |
WebP文件格式基于RIFF(资源交换文件格式)文档格式。
RIFF文件的基本元素是一个块。它包括:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk FourCC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Payload |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RIFF有一个约定,所有大写字母的FourCC是适用于任何RIFF文件格式的标准块,而特定于文件格式的FourCC都是小写的。 WebP不遵循此约定。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'R' | 'I' | 'F' | 'F' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| File Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'W' | 'E' | 'B' | 'P' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
这种文件格式支持有损编码,但不包含透明度以及其他拓展特性,可以被许多旧版本软件支持。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| WebP file header (12 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8 chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+VP8 chunk:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8 ') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8 data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Chunk Header:VP8块首部,定义了VP8比特流数据的大小,以及该帧VP8数据的长宽等信息。
VP8 data:VP8比特流数据。
VP8比特流格式的定义可参考rfc6386,主要定义了如何将图像数据转换成YUV格式。
无损WebP简要文件格式
这种格式用在无损WebP编码(可选透明)并且不要求拓展特性时。需要注意的是,较旧的WebP软件可能不支持该格式。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| WebP file header (12 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8L chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VP8L chunk:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8L') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8L data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+属性意义类似于有损WebP的简要格式,其中VP8L的定义可参考文档:https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
拓展格式包括:
对于静态图像,图像数据包含一帧数据,由以下组成:
拓展头部格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| WebP file header (12 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8X') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Canvas Width Minus One | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Canvas Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
WebP动画被ANIM和ANMF块所控制。
ANIM Chunk:
对于一个动图,该块数据定义了动画的全局参数。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANIM') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Background Color |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Loop Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
当动画标识被置位时,该数据块必须出现。当动画标识位没出现时,该数据块会被忽略。
ANMF chunk:
对于动图,该数据块包含了一帧图像的数据。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANMF') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame X | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Frame Y | Frame Width Minus One ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Frame Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame Duration | Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ALPH') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C | Alpha Bitstream... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
颜色配置文件Color profile、元数据Metadata数据的文件格式类似,主要是头部ASCII码不同。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ICCP') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Color Profile |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Metadata
EXIF chunk:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('EXIF') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EXIF Metadata |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+XMP chunk:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('XMP ') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| XMP Metadata |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+原理
WebP的压缩主要分为有损压缩lossy、无损压缩lossless以及有损带透明通道压缩alpha。主要原理可参照官方文档webp-compression
有损WebP基于VP8视频编码中的预测编码方法来压缩图像数据,其基本步骤类似于JPEG压缩,主要包含格式转换、分割子块、预测编码、FDCT、量化、Z排列、熵编码,流程如下图所示,红色代表与JPEG不同的部分。
基于以上压缩算法,可以得出为什么lossy WebP会比JPEG好:
提到WebP的有损压缩算法就不得不提到VP8视频格式。
无损WebP基于使用不同的技术对图像数据进行转换,包括:预测空间变换、色彩空间转换、使用调色板、多像素打包成一个像素、alpha值替换等技术。对于熵编码,则采用改进的LZ77-Huffman编码来紧凑稀疏值,它是一种对距离值的2D编码技术。
区别于有损WebP和无损WebP,这种编码允许对RGB频道的有损编码同时可对透明度频道进行无损编码。由于这种形式目前其他的格式还未能提供,所以目前需要使用透明度的话都会使用无损的PNG,导致大小膨胀。对于这类图片,WebP提供了较好的压缩效果。相比有损的WebP,添加透明通道只增加22%的大小。
因此,将支持透明的PNG换成无损+支持透明的WEBP可以平均节省60%-70%大小,这个已经被一些含较多Icon的移动网站证明。
动态WebP的原理与GIF和APNG原理类似,每一帧记录变化区域的坐标、长宽、播放延时等用于还原并播放。
方式1.通过使用一张很小的webp图片确认当前环境是否支持:
// check_webp_feature:
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
function check_webp_feature(feature, callback) {
var kTestImages = {
// 有损
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
// 无损
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
// 透明
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
// 动画
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
};
let img = new Image();
img.onload = function () {
var result = (img.width > 0) && (img.height > 0);
callback(feature, result);
};
img.onerror = function () {
callback(feature, false);
};
img.src = "data:image/webp;base64," + kTestImages[feature];
}方式2.通过canvas试图创建webp格式图片确认
window.IS_SUPPORT_WEBP = (!![].map &&
document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') === 0);微信web不支持,微信小程序支持
iOS14开始支持
如果是原生app开发,iOS和Android都可以通过使用官方提供的解析库来支持静态WebP https://github.com/carsonmcdonald/WebP-iOS-example,https://github.com/alexey-pelykh/webp-android-backport。
然而,对于动态WebP,目前只能找到facebook的开源库Fresco对其支持,不过Fresco最低仅支持API 9,且引用的相关库较多。