使用开源软件和库对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兼容。

分享这篇文章
订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论