在保证图片质量的情况下,AVIF文件的格式,比起其它格式的文件来说,它能实现文件占内存小的优势,这算得上是Android 12的一个新特性。最近,杰克·阿奇博尔德(Jake Archibald)将AVIF格式与JPEG、WebP和其他静态图片格式进行了比较,并进行了一个测评,发现其结果十分令人惊喜。
对比发现,除了在Android 12上可以输出该格式的文档,它在Chrome浏览器上也可以输出。而Firefox 86也默认启用了该功能,本文我将介绍一些可以操纵AVIF图片的开源程序和库。
首先,针对libavif库、avifenc和avifdec工具,还有各种编解码器,AOMedia发布了一款C语言的参考实现。显然rav1e被用在了编码AVIF图片,不过dav1d才是AVIF解码的最佳选择。
libavif不会自动生成编解码器,这需在CMakeLists.txt中才能得以启用。
1 2 3 4 5 |
option(AVIF_CODEC_AOM "Use the AOM codec for encoding/decoding (see AVIF_CODEC_AOM_DECODE/AVIF_CODEC_AOM_ENCODE)" OFF) option(AVIF_CODEC_DAV1D "Use the dav1d codec for decoding" ON) option(AVIF_CODEC_LIBGAV1 "Use the libgav1 codec for decoding" OFF) option(AVIF_CODEC_RAV1E "Use the rav1e codec for encoding" ON) option(AVIF_CODEC_SVT "Use the SVT-AV1 codec for encoding" OFF) |
在CMakeLists.txt中,去定义所选编解码器的路径。
rav1e AVIF编码库和cavif-rs工具
在Ubuntu 20.04中构建rav1e:
1 2 3 4 |
git clone https://github.com/xiph/rav1e cd rav1e sudo apt install cargo nasm cargo build --release |
这项测评是在AMD Ryzen笔记本电脑上进行的,但rav1e同时针对Arm和x86进行了优化:
- asm–默认情况下启用。启用后,将为支持该程序的平台构建程序集
- x86_64:需要 nasm
- aarch64
- 需要 gas
- 备选:通过设置CC=clang使用汇编程序clang
注意:在x86_64上始终启用SSE2,在aarch64上始终启用neon,你可以将环境变量RAV1E_CPU_TARGET设置为rust,以在运行时禁用所有程序集优化例程。
rav1e基于rust,但也有一个C库,包含头文件和pkg-config文件,可供想要将rav1e集成到其C项目中的开发者使用。生成方法如下:
1 2 |
cargo install cargo-c cargo cinstall --release |
rav1e可对源视频进行编码,但afaik没有过对AVIF图片文件进行编码的例子,因此此次测评用libavif或cavif-rs从PNG或JPG文件生成AVIF文件。
下面展示如何在Ubuntu 20.04中构建cavif-rs:
1 2 3 |
git clone https://github.com/kornelski/cavif-rs cd cavif-rs cargo install cavif |
请注意: rav1e将在此过程中进行编译,故无需事先构建rav1e。然后,运行该程序进行测试:
1 2 3 4 5 6 7 |
export PATH=$PATH:/home/jaufranc/.cargo/bin time cavif cnxsoft-logo.png cnxsoft-logo.avif: 30KB (29221B color, 0B alpha, 188B HEIF) real 0m4.753s user 0m17.945s sys 0m0.064s |
在AMD Ryzen 7 2700U处理器上将PNG文件转换为AVIF文件花了将近五秒钟,但文件现在确实小多了:
1 2 3 |
ls cnxsoft-logo.* -l -rw-rw-r-- 1 jaufranc jaufranc 29409 Feb 23 11:05 cnxsoft-logo.avif -rw-r--r-- 1 jaufranc jaufranc 205216 Feb 23 11:03 cnxsoft-logo.png |
综合所有的格式处理器而言,如果需要无损PNG格式,AVIF文件可能不是最佳的选择。但如果在Chrome中打开文件,基本没有差异:

dav1d AVIF解码库和davif工具
一般的嵌入式系统,大多数会用AVIF来解码/渲染。为此,构建了一个dav1d C库参与到这个测评中来进行测试:
1 2 3 4 5 6 |
git clone https://code.videolan.org/videolan/dav1d cd dav1d/ sudo apt install nasm meson ninja-build mkdir build && cd build meson .. ninja |
就像rav1e一样,dav1d已针对Arm和x86目标进行了优化。
在工作时,编解码器针对带有NEON SIMD指令的64位Arm处理器和带有AVX2和SSSE3 + SIMD指令的x86芯片的汇编代码进行了优化。
对于ARMv7(32位arm)和较少常见的PPC、SSE2或AVX-512的工作仍在进行中。
该代码也可集成到程序中,但如果想要得到可以用dav1d将解码/转换的AVIF文件的一个示例代码,则可以用davif工具将一个AVIF文件转换为PNG。
在Ubuntu 20.04构建:
1 2 3 4 |
git clone --recurse-submodules --recursive https://github.com/link-u/davif cd davif cmake . make |
从AVIF到PNG的转换要比其他方法快得多,更准确地说,要快10倍以上。
1 2 3 4 5 6 7 8 9 |
time ./davif -i cnxsoft-logo.avif -o cnxsoft-logo.png [2021/02/23 11:51:15 INFO ] davif [2021/02/23 11:51:15 DEBUG] - dav1d ver: 0.8.0-34-g7424f8e [2021/02/23 11:51:15 INFO ] Decoding: cnxsoft-logo.avif -> cnxsoft-logo.png [2021/02/23 11:51:15 INFO ] Decoded: cnxsoft-logo.avif -> cnxsoft-logo.png in 93 [ms] real 0m0.392s user 0m0.431s sys 0m0.012s |
由于所有内容都是用C和汇编程序编写的,因此可能更容易移植到资源受限的嵌入式系统。
需要指出的是,AVIF并不是唯一的新图片格式,因为JPEG XL最近也在开发了。但如果要集成到Web浏览器中,我估计还需要更长的时间。关于JPEG XL的参考实现,你们可以在Gitlab上找到。
至于AVIF和JPEG XL之间的区别,在encode.su论坛上和Cloudinary博客上有相关的讨论。讨论中也有提及到AVIF能够提供更好的压缩,但JPEG XL解码器(尤其是编码器)应该会更快,并且能支持更大的分辨率,而AVIF限制为3840×2160,这似乎就有点奇怪。JPEG XL没有版税,而且保持与JPEG兼容。

文章翻译者:Jacob,嵌入式系统测试工程师、RAK高级工程师,物联网行业多年工作经验,熟悉嵌入式开发、测试各个环节,对不同产品有自己专业的分析与评估。