凹凸君: GIF 存活 29 年之久,依然大行其道的今天,有没有更合适的动画格式?
回答: 或许,可以聊聊 APNG。
关于 APNG
APNG(Animated Portable Network Graphics)顾名思义是基于 PNG 格式扩展的一种动画格式,增加了对动画图像的支持,同时加入了 24 位图像和 8 位 Alpha 透明度的支持,这意味着动画将拥有更好的质量,其诞生的目的是为了替代老旧的 GIF 格式,但它目前并没有获得 PNG 组织官方的认可。
APNG 简史
MNG
在 APNG 之前它还有一个老冤家叫 MNG(Multiple-image Network Graphics)即多图像网络图形,1996 年 6 月提出 PNF(Portable Network Frame)草案,同年8月更名为 MNG ,2001 年 1 月 31 日发布 MNG 规范 1.0 版本,MNG 是出自 PNG 开发组之手,但由于结构复杂的 MNG 程序库,使用过程会占用大量的资源,早期只有较少的浏览器支持,Chrome、IE、Opera、Safari 则从未支持过。
APNG
2004 年,由 Mozilla 公司两位 Mozilla 程序员 Stuart Parmenter 和 Vladimir Vukićević 共同设计出 APNG,他们希望 Mozilla 社区能使用它,但提案未能通过。
libpng程序库
2006 年,Google Summer of Code 活动中,加拿大圣力嘉学院的学生为 libpng 程序库加入了对 APNG 支持,此后开发者再次推荐给 Mozilla 社区,不过仍然遭到拒绝。
首次支持
2007 年 3 月 23 日,Mozilla 后知后觉,在 Mozilla Firefox 3.0 中 首次支持 APNG 格式。
标准化申请
2007 年 4 月 20 日,Mozilla 希望 APNG 能成为官方标准,因此 PNG 组织发起投票,最终以8:10的票数否决了 APNG 进了官方标准,因为 PNG 组织决心继续推广 MNG,但这不并影响 Mozilla 继续支持 APNG。
为什么 GIF 能存活29年之久?
开头讲 APNG 时提到,APNG 的出现就是为了替代 GIF,诞生于 1987 年的 GIF 为什么能存活 29 年之久?
主要有四个原因:
几乎所有的主流浏览器都支持 GIF
早期选择不多,GIF 几乎是唯一选择(GIF - 1987、JPEG - 1992、PNG - 1996、APNG - 2004、WebP - 2010)
实现起来简单,制作的工具多
采用 LZW 数据压缩算法,使得 GIF 体积小,在早期慢速的互联网易于传播
为什么要取代它?
1、图片质量
GIF
APNG
如果你使用的是非 Firefox、Safari 浏览器,那 APNG 格式的图片会向下兼容显示为静态图,你可以更换 Firefox、Safari 浏览器或者在 Chrome 浏览器安装 APNG Extension for Google Chrome 扩展来兼容,通过两者对比能总结出以下区别:
GIF:
最多支持 8 位 256 色,色阶过渡糟糕,图片具有颗粒感
不支持 Alpha 透明通道,边缘有杂边
APNG:
支持 24 位真彩色图片
支持 8 位 Alpha 透明通道
向下兼容 PNG
2、图片体积
如果你使用的浏览器不支持WebP,下面对比的 WebP 格式的图片将无法显示。
GIF = 43 920 bytes
APNG = 34 210 bytes
WebP = 41 064 bytes
Lossy WebP = 73 774 bytes
GIF = 43 132 bytes
APNG = 30 823 bytes
WebP = 55 968 bytes
Lossy WebP = 114 518 bytes
GIF = 200 700 bytes
APNG = 168 411 bytes
WebP = 424 752 bytes
Lossy WebP = 394 118 bytes
P
从几组 GIF、APNG、WebP 的对比中可以发现,无论在纯色的图片或是多彩的图片,大部分情况下 APNG 依旧能比 GIF、WebP 以及有损的 WebP 的体积小。
APNG 的组成
APNG 是基于 PNG 格式扩展的,首先需要了解一个简单的 PNG 文件组成结构:
PNG Signature
IHDR
IDAT
IEND
PNG 由 4 部分组成,首先以 PNG Signature(PNG签名块)开头,紧接着一个 IHDR(图像头部块),然后是一个或多个的 IDAT(图像数据块),最终以 IEND(图像结束块)结尾。
APNG 规范引入了三个新大块,分别是:acTL(动画控制块)、fcTL(帧控制块)、fdAT(帧数据块),下图是三个独立的 PNG 文件组成 APNG 的示意图。
acTL 块必须在第一个 IDAT 块之前,用于告诉解析器这是一个动画 PNG,包含动画帧总数和循环次数的信息
fcTL 块是每一帧都必须的,出现在 IDAT 或 fdAT 之前,包含顺序号、宽高、帧位置、延时等信息
fdAT 块与 IDAT 块有着相同的结构,除了 fcTL 中的顺序号
从图中可以发现第一帧与后面两帧不同,那是因为第一帧 APNG 文件存储的为一个正常的 PNG 数据块,对于不支持 APNG 的浏览器或软件,只会显示 APNG 文件的第一帧,忽略后面附加的动画块,这也是为什么 APNG 能向下兼容 PNG 的原因。
APNG 帧间优化
假设使用一个 4 帧图片合成 APNG
APNG 会通过算法计算帧之间的差异,只存储帧之前的差异,而不是存储全帧。
通过 TweakPNG 软件观察 IDAT 图像数据块和 fdAT 帧数据块的大小,可以明显的看出来存储全帧与差异帧的区别,使得 APNG 文件大小有显著的减少。
为什么没有普及?
主要的原因是缺乏浏览器的支持,从 Can I use 查询可知 Firefox 从 3 到 49 版本自始自终支持着,Opera 早期只有三个版本支持过(10.1、11.5、12.1),后续版本则取消了对 APNG 的支持,而 Chrome、IE、Edge 则从未支持过 APNG,Chrome 和 Opera 都在推广自家的 WebP,而微软则一直是个不合群的家伙。
但是,重要的一点是 2014 年 9 月 17 号 Apple 向用户推送了 iOS 8,这意味着 Safari 8 新增了对 APNG 的支持,这能有效的推动 APNG 的发展,至少在移动端。
特性检测
既然存在兼容问题,那就需要通过判断应用场景。
(function() {
"use strict";
var apngTest = new Image(),
ctx = document.createElement("canvas").getContext("2d");
apngTest.onload = function () {
ctx.drawImage(apngTest, 0, 0);
self.apng_supported = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
};
apngTest.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==";}());
方法与 WebP 检测相似,同样是加载一张 1x1 像素大小的 Base64 编码图片,不同在于 WebP 加载完成后是判断图片宽高是否大于 1,而 APNG 则是将其绘制到画布中,通过 getImageData() 方法去获取该图片的像素数据,主要是获取 data[3] 的 Alpha 透明通道(值的范围:0 - 255),当返回 0(0代表透明的)时则表示支持 APNG,返回 255(255 代表完全可见的)则表示不支持 APNG。
APNG to Canvas
当然,目前也有用于兼容的库:apng-canvas
使用该库需要以下条件支持:
Canvas
Typed Arrays
Blob URLs
requestAnimationFrame
APNG.ifNeeded().then(function() { var images = document.querySelectorAll(".apng-image"); for (var i = 0; i < images.length; i++) { APNG.animateImage(images[i]); }});
DEMO 戳这里
制作工具
在了解 APNG 后,是不是心痒痒想制作 APNG 呢?在制作工具方面,APNG 已经不像早期那样工具匮乏了,APNG Software 网站上有大量的制作工具,有客户端版本(大部分只支持 Widnows)也有命令行版本,可以非常轻松的制作 APNG,比如下面这款软件。
Windows客户端 - APNG Assembler
Mac客户端 - APNGb
功能说明:
Playback Settings 可设置循环的次数,0 表示无限循环,可跳过第一帧
Delays - All Frames 可设置所有帧播放时所停留的时间
Compression Settings 可设置压缩参数,有三种压缩方式(zlib、7zip、Zopfli)以及颜色类型和调色板优化
Delays - Selected Frames 可设置选中帧播放时所停留的时间
这里演示图分别是 Windows 版本和 Mac 版本,功能基本一致,将序列帧图片拖拽到指定位置,设置一些基本的参数即可生成 APNG 图,Mac 版本比 Windows 版本多出一个将 APNG 图片 Disassembly(分解)功能,可分解为多个 PNG 图片。
下载地址戳这里
投票呼吁
在最后,如果你认为 APNG 是值得被支持、被推广的,请为它投上一票和点 Stars(需科学上网)。
APNG support in Chrome : issue 1171、issue 437662
APNG support in IE : Votes
感谢你的阅读。
参考资料
Animated PNG demos
GIF vs APNG vs WebP
Inter-frame Optimization in APNG
davidmz/apng-canvas - Github
GIF - Wikipedia
APNG - Wikipedia
APNG Specification
Can I use - APNG
Portable Network Graphics - Wikipedia
Multiple-image Network Graphics - Wikipedia
APNG Software
感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室
本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。