浏览器能显示AVIF,却导不出一张AVIF

想给自己的小项目加一个「导出为 AVIF」的选项,我原本以为是十分钟的事。AVIF 这个格式比较新,我是冲着它文件小去的,而且我手边几个浏览器都能直接显示 .avif 的图。既然能显示,我就默认它们也能把图存成这个格式。结果存下来的文件后缀写的是 .avif,一读类型,是 image/png。

为了确认不是我哪里写错了,我搭了个很小的测试页。页面上是一块 640×360 的画布,调的是 toBlob。这是画布自带的方法,你指定一种格式,它就把画的东西按那种格式交出一个文件。格式我写的是 image/avif,质量给 0.8。我在一台 Apple M4 的 Mac 上换了四个浏览器各跑一遍。Chromium 149、Chrome 155、Firefox 151 都没有报错,交回来的类型却全是 image/png。Chromium 那份有 178,010 字节,跟我老老实实要 PNG 时一个字节都不差。交回 image/avif 的只有 WebKit 26.5 一个,大小是 2,256 字节。我跑的是 macOS 上的 WebKit,Safari 正式版会怎样我不知道。那份 AVIF 我也只抄了类型和大小,没看画质,也没计时。

这张图看左边那一列就够了。上面三行红色的格子都是 image/png,最下面绿色那格是 WebKit 26.5 交回的 image/avif。右边 WebP 那一列是顺手做的对照,这篇不展开。

接着我在同一个页面里反过来试了一次。我拿了一张 388×258 的 AVIF 文件让四个浏览器去解。用的接口是 createImageBitmap,它负责把图片文件变回一格一格的像素。四个全都解开了。这下两件事就分开了。把文件还原成像素叫解码,显示一张图只需要这一步。把像素压成文件叫编码,保存的时候才用得上。两件事方向相反,会前一件不代表会后一件。我自己是拿超市的扫码枪记的:它什么条形码都读得出来,可它印不出一张条形码,要印得另外配一台标签机。我之前把「能显示」当成了「支持 AVIF」的全部,其实那只是扫码枪那一半。至于那三个浏览器为什么没带另一半,我没去查,手里只有现象。

标签机得自己带。前端的做法是加载一个 WASM 编码器。WASM 是一种能在浏览器里运行的二进制程序,别人用 C 写好的编码库编成这种格式以后,网页就能直接调用它。我用的是 @jsquash/avif 2.1.1,里面装的是 libavif v1.0.1。它的单线程编码文件原始大小是 3,485,872 字节。gzip 是服务器传文件前常用的压缩方式,我自己用它压了一遍,是 1,115,948 字节,约 1 MB。换成 brotli 压是 842,416 字节。拿来对照的是 @jsquash/webp 1.5.0。它的 WebP 编码文件原始 281,261 字节,gzip 之后 113,848 字节,约 0.1 MB。同样是「自己带一个编码器」,AVIF 这个差不多是 WebP 那个的十倍。这些是我自己压出来的数,线上服务器实际压成多大要看各自的配置。

这 1 MB 是头一回用的时候要下载的。下载完以后的事反而不大。在我这台机器的 Chromium 149 里,把它实例化三次分别用了 14、13、12 毫秒。WebP 那个是 4 毫秒。实例化的意思是让这段程序跑起来、可以被调用。下载本身要多久我给不出数字,因为测试页的文件就放在本机,不走网络。

我还想看看现成的在线工具怎么安排这 1 MB。我用的是图映 ImgIng(imging.cn/),在 Chromium 149 里拿一张 200 万像素的湖景图走了一遍转 AVIF。它的格式按钮上,WebP、JPG、PNG 标的是「即时」,AVIF 标的是「按需 WASM」。我一选中 AVIF,编码文件就开始下载了,没有等到我点转换。请求到的是多线程那一版,传输了 1,135,337 字节,也是 1 MB 出头。加载过一次以后,AVIF 上的标签变成了「即时」。选中之后页面上还多出一行说明,意思是 AVIF 浏览器自己编不了,得先把编码器加载进来。这一轮我每档图只跑了一次,也只用了这一个浏览器,它的源码我没读。它界面上的等待是从页面外面看到的整段时间,和我测试页里量的那十几毫秒实例化不是一个口径,不能摆在一起比。

这是转完之后的面板。AVIF 那个按钮角上的字变成了「即时」,尺寸 1738×1150 后面跟着「WASM AVIF 编码器」。「省 98%」是拿 58.9 KB 和我传进去的 2.65 MB 比出来的。传进去的是 PNG,所以这个数不是在说 AVIF 比别的格式好多少。湖景这张图来自维基共享资源,Jakub Fryš 拍的,CC BY-SA 4.0 许可。

现在我看一个格式「支不支持」,会分开问两句:能不能显示,能不能导出,各试各的。导不出的话,先把那 1 MB 算进这个功能的成本,再去算每张图要等多久。WebKit 交回来的那 2,256 字节和 WASM 编码器出来的差多少,我还没比过,先留着。

相关推荐
小皮虾1 小时前
小程序全局状态还能这么简单?只需初始化一次,页面自动同步
前端·javascript·微信小程序
用户818618028001 小时前
RESTful API 设计规范与版本演进
前端
补码缩写1 小时前
前端AVIF编码开多线程快两三倍,speed调到8就不快了
前端
cidy_981 小时前
企业级 AI Agent 工作台前端实战教程
前端
deli0071 小时前
换个 DNS 网速真的变快吗?解析 6 步逐跳实测,快慢差 45 倍
前端
葡萄城技术团队1 小时前
接一个前端库:以前要啃几天文档,现在三步——活字格 V12.1 AI辅助开发上手
前端
愿得一猪蹄1 小时前
浏览器开发者工具隐藏技巧,你可能只用了一成
前端
高晶2 小时前
ARM 嵌入式 Linux 内核编译与结构解析实战
前端·架构
今年下半年2 小时前
【前端】Vue2 项目 ECharts 统计图表组件封装与使用实践(附组件源码)
前端·javascript·echarts