使用开源软件和库对AVIF图片进行编码和解码

原文链接:Encoding and decoding AVIF pictures with open-source software & libraries 由Jean-Luc Aufranc撰写。

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中得以启用。


在CMakeLists.txt中,去定义所选编解码器的路径。

rav1e AVIF编码库和cavif-rs工具

在Ubuntu 20.04中构建rav1e:


这项测评是在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项目中的开发者使用。生成方法如下:


rav1e可对源视频进行编码,但afaik没有过对AVIF图片文件进行编码的例子,因此此次测评用libavif或cavif-rs从PNG或JPG文件生成AVIF文件。

下面展示如何在Ubuntu 20.04中构建cavif-rs:


请注意, rav1e将在此过程中进行编译,故无需事先构建rav1e。然后,运行该程序进行测试:


在AMD Ryzen 7 2700U处理器上将PNG文件转换为AVIF文件花了将近五秒钟,但文件现在小多了:


综合所有的格式处理器而言,如果需要无损PNG格式,AVIF文件可能不是最佳的选择。但如果在Chrome中打开文件,基本没有差异:

AVIF(左)与PNG(右)
AVIF(左)与PNG(右)

点击PNGAVIF,可打开查看文件源。

dav1d AVIF解码库和davif工具

一般的嵌入式系统,大多数会用AVIF来解码/渲染。为此,构建了一个dav1d C库参与到这个测评中来进行测试:


就像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构建:


从AVIF到PNG的转换要比其他方法快得多,更准确地说,要快10倍以上。


由于所有内容都是用C和汇编程序编写的,因此可能更容易移植到资源受限的嵌入式系统。

需要指出的是,AVIF并不是唯一的新图片格式,因为JPEG XL也在开发中了。但如果要集成到Web浏览器中,还需要更长的时间。关于JPEG XL的参考实现,你们可以在Gitlab找到。

至于AVIF和JPEG XL之间的区别,在encode.su论坛上和Cloudinary博客有相关的讨论。讨论中也有提及到AVIF能够提供更好的压缩,但JPEG XL解码器(尤其是编码器)应该会更快,并且能支持更大的分辨率,而AVIF限制为3840×2160,这似乎就有点奇怪。JPEG XL没有版税,而且保持与JPEG兼容。

分享这篇文章
<-- Multiplex code - to do -->
0 评论
内联反馈
查看所有评论