在介绍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的特点是支持非破坏新编辑和动画、音频(苹果的Live Photo)。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的又一个继任者(JPEG2000、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还有尚不明确的WebP2。
相关工具