在介绍 WebP 的时候,我们已经知道了相比 JPG 和 PNG 来说,WebP 已经兼顾了高呈现质量以及更小的文件体积,可以说已经非常优秀了,然后还是有一群人不满足于此,他们开发出了 AVIF 这种号称下一代图像压缩格式的玩意。
AVIF简介
AVIF(AV1 Image File Format)是一种开源的、高效的图像文件格式。它是由联盟开放媒体项目(AOMedia)的 AV1 视频格式衍生而来的,用于更有效地编码图像数据。AVIF 提供了比传统的 JPEG 和其他图像格式更高的数据压缩性能,同时也提供了更高的图像质量。
AVIF 这种图像格式首次是由 Netflix 这个公司在 2020年2月14号这天公布的。Netflix(奈飞)是一家流媒体影视公司,所以必然会有大量的影视海报,它们都是体积很大的大图片。因此 Netflix 对呈现质量有很高的要求,同时又希望图片体积能尽可能的小,所以他们一直在探寻一种新的图像格式希望能替换 JPG。
事实上,AVIF 这种图像格式是由开放媒体联盟(aomedia.org)与 Google、Cisco 以及 Xiph.org 合作开发出来的。这种格式被创建为一种开源且免版税的图像格式,不像 JPEG XR,它是一种压缩非常小但需要昂贵许可才能实现的文件格式。
AVIF 的主要优势包括:
- 高效的压缩:与 JPEG,PNG,GIF 等格式相比,AVIF 可以在相同的文件大小下提供更好的图像质量,或者以更小的文件大小提供相同的图像质量。
- 丰富的颜色深度:AVIF 为每个颜色通道提供高达10位或12位的颜色深度,这比许多传统格式提供的8位深度更高,可以更准确地表示颜色。
- 高动态范围(HDR)和宽色域(WCG):AVIF 支持高动态范围(HDR)和宽色域(WCG),也就是说,它可以包含更明亮的亮点,更深的黑色,以及比标准动态范围图像更广的颜色范围。
- 透明度支持:AVIF 支持 alpha 透明度(也就是每个像素可以有其自己的透明度级别),类似于 PNG 和 GIF 格式。
- 兼容性:AVIF 由多个大型科技公司(包括 Google,Netflix,Amazon,Microsoft 等)所支持,并已经在一些主流浏览器(如 Chrome 和 Firefox)中实现。
总的来说,AVIF 是一种新兴的图像格式,它在压缩效率、颜色表现、HDR 和 WCG 支持等方面都优于传统的图像格式,有望在未来的网络和媒体应用中得到更广泛的使用。
与WebP 的比较
国外有个程序员 Daniel Aleksandersen 写了一个博客,然后他希望他博客的图片尽可能小的占用网络带宽,但是他在犹豫使用什么格式的图像会比较好,所以他决定亲自探索一翻。
他使用了大于 600 张的图片,通过将他们基于相同的 DSSIM 情况下编码成不同格式的图片。
然后通过对比这些大量的不同格式的图片数据,他得到的结论是:
类型 | 50分位数压缩率 | 85分位数压缩率 |
WebP | -30% | -20% |
AVIF | -50% | -40% |
AVIF 和 WebP 都是现代的图像文件格式,它们都旨在提供比传统格式(如 JPEG 和 PNG)更高效的图像压缩。然而,它们之间还是有一些关键的区别的:
- 压缩效率:AVIF 大约可以提供比 WebP 更高 20%-30% 的数据压缩效率,这意味着在同等图像质量的条件下,AVIF 文件的大小比 WebP 文件的大小更小。
- 颜色深度:AVIF 支持高达 10 位或 12 位的颜色深度,而 WebP 的颜色深度限制为 8 位。这意味着 AVIF 可以提供更丰富、更精细的颜色。
- HDR 和 WCG:AVIF 支持高动态范围(HDR)和宽色域(WCG),而 WebP 不支持。这使 AVIF 能够展示更明亮的亮点、更深的黑色和更广的颜色范围。
- 透明度:AVIF 和 WebP 都支持alpha透明度,也就是说,每个像素可以有其自己的透明度级别。
- 支持和兼容性:WebP 格式由 Google 开发,目前在各大浏览器和许多应用程序中都得到了广泛支持。而 AVIF 是一种更年轻的格式,虽然已经得到了 Google、Netflix、Amazon、Microsoft 等公司的支持,但目前在浏览器和应用程序的支持情况还不如 WebP。
总的来说,AVIF 在技术参数上(如压缩效率和颜色深度)表现优于 WebP,但在设备和软件的兼容性方面,WebP 当前的支持度更高。随着时间的推移,AVIF 的兼容性和支持度可能会提高。
AVIF的兼容性
AVIF兼容多种浏览器。关于AVIF格式图片兼容的浏览器及其版本,请参见AVIF兼容性。
不兼容浏览器的解决方案
方案一:使用picture标签
采用HTML的picture标签,在picture标签中填写一个source标签和一个img标签,source标签设置为AVIF图片。浏览器会优先显示AVIF图片,如果浏览器渲染AVIF图片失败,就会再次请求img标签内的图片并正常渲染:
<picture> <source srcset="img/photo.avif" type="image/avif"> <source srcset="img/photo.webp" type="image/webp"> <img src="img/photo.jpg" alt="Description of Photo"> </picture>
方案二:使用CSS+JS方式
除了使用picture标签外,还可以使用CSS+JS的方式,兼容显示AVIF图片。使用supportsAvif方法判断浏览器是否支持AVIF,如果支持就设置div的样式为avif,背景图片设置为AVIF图片。如果不支持就会设置div的样式为no-avif,背景图片设置为原图(其他格式备用图片也可以),具体代码如下所示:
JS代码
async function supportsAvif() { if (!this.createImageBitmap) return false const avifData = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=' const blob = await fetch(avifData).then((r) => r.blob()) return createImageBitmap(blob).then( () => true, () => false ) } ;(async () => { const classAvif = (await supportsAvif()) ? 'avif' : 'no-avif' document.body.classList.add(classAvif) })()
CSS代码
div { background-repeat: no-repeat; background-size: 500px 200px; width: 500px; height: 200px; } .avif div { background-image: url(https://image-compress-demo.oss-cn-zhangjiakou.aliyuncs.com/demo.jpg?x-oss-process=image/format,avif); } .no-avif div { background-image: url(https://image-compress-demo.oss-cn-zhangjiakou.aliyuncs.com/demo.jpg); }
方案三:使用JS解码
avif.js这个方案的特点是非常的轻量,生产版本只需要不到4kb。它依赖service worker的请求拦截特性,当页面发出fetch操作时,它可以将请求拦截住,然后给出自己的响应。
这样就能在请求完AVIF格式的图片以后,在service worker当中调用解码器,将图片转码。同时,因为是运行在service worker线程当中,解码操作并不会阻塞UI线程。
方案四:WebAssembly
js做编解码的事情不是特别合适,如果用c语言来做编解码的事情,岂不是更好,目前社区关于WebAssembly的热度很高,发现已经有使用WebAssembly来做AVIF的编解码。
webassembly/packages/avif at main · saschazar21/webassembly (github.com)
AVIF图片的转化
使用编程语言转换图片到 AVIF 格式需要借助一些库或工具。以下是一些使用 Python, PHP, Java, NodeJS, 和 Go 语言转换图片的示例:
Python
你可以使用 pyavif 库。首先安装库 pip install pyavif,然后使用以下代码:
from PIL import Image from pyavif import AVIF img = Image.open('input.jpg') avif_img = AVIF(img) avif_img.save('output.avif')
PHP
在 PHP 中,你可以使用 Imagick 扩展进行图像转换。注意,你需要在服务器上安装支持 AVIF 的 ImageMagick。
$image = new Imagick('input.jpg'); $image->setImageFormat('avif'); $image->writeImage('output.avif');
Java
目前 Java 没有直接支持 AVIF 格式的库。你可能需要调用系统命令执行 ImageMagick 或者其他转换工具,或者使用 JNI 调用 C 语言的 libavif 库。
Node.js
在 Node.js 中,可以使用 sharp 库进行图像格式转换。首先安装 sharp(npm install sharp),然后使用以下代码:
const sharp = require('sharp'); sharp('input.jpg') .avif({ quality: 50 }) .toFile('output.avif');
Go
在 Go 中,可以使用 image 库读取图像,然后使用 go-avif 库进行转换。
package main import ( avif "github.com/Kagami/go-avif" "image/jpeg" "os" ) func main() { // Open JPEG file imgFile, _ := os.Open("input.jpg") defer imgFile.Close() // Decode JPEG img, _ := jpeg.Decode(imgFile) // Create AVIF file avifFile, _ := os.Create("output.avif") defer avifFile.Close() // Encode AVIF opts := &avif.Options{ Speed: avif.SpeedFastest, } _ = avif.Encode(avifFile, img, opts) }
请注意,以上代码仅作示例用途。在实际使用中,你还需要处理错误,并确保你的环境正确地安装了所需的库和工具。
其他次世代图片格式
- HEIF是MPEG(动态影像专家组) 于 2015 年发布,基于 HEVC (H.265) 视频编解码器。HEIF 的特点是支持非破坏新编辑和动画、音频(苹果的 LivePhoto)。HEIF 目前在苹果设备上被广泛使用,iPhone 相机保存的照片已经是 HEIF 了。但是苹果的 Safari 浏览器并不支持,原因应该是它使用的 HEVC (H.265) 的专利限制。
- BPG是 Fabrice Bellard(FFmpeg、QEMU、QuickJS 的作者) 于 2014 年发布,基于 HEVC (H.265) 视频编解码器 。 BPG 引领了基于 HEVC (H.265) 的图片格式 HEIF ;由于专利原因,更加正统的 HEIF 取代了 BPG。
- FLIF是 2015 年由其开源社区发布的专注无损压缩的图片格式,后被合并到 FUIF (免费的通用图像格式) ,最后发展成 JPEG XL。
- JPEG XL是 JPEG(联合影像专家组) 2021 年完成的 JPEG 的又一个继任者(JPEG 2000、JPEG XR)。JPEG XL 是一个令人惊喜的图片格式,一改 JPEG(联合影像专家组) 保守、专利限制严格的印象,不仅开源、免专利还与开源社区有积极联系,吸收了FLIF 格式最为其无损压缩部分。
- WebP2是谷歌在 2021 年公开的 WebP 继任者,主要目标是让其有损压缩能力达到 AVIF ,并且增加 HDR10、快速解码等 WebP 缺失的功能,其无损压缩也有提升。
在次世代的图片格式中,BPG 被同样使用 HEVC (H.265) 并且有苹果设备支持的 HEIF 取代,而由于专利原因 HEIF 难有更广泛的使用机会,与此相使用 AV1 的 AVIF 是 HEIF 的平替,没有专利问题,有浏览器支持。JPEG XL 吸收了 FLIF ,并且同样没有专利问题。
所以最后剩下的次世代格式就是 AVIF、JPEG XL 还有尚不明确的 WebP 2。
相关工具