APNG 那些事

Wesley13
• 阅读 1529

APNG 那些事

凹凸君: 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、图片质量

APNG 那些事 APNG 那些事 APNG 那些事 APNG 那些事 APNG 那些事

GIF

APNG 那些事 APNG 那些事 APNG 那些事 APNG 那些事 APNG 那些事

APNG

如果你使用的是非 Firefox、Safari 浏览器,那 APNG 格式的图片会向下兼容显示为静态图,你可以更换 Firefox、Safari 浏览器或者在 Chrome 浏览器安装 APNG Extension for Google Chrome 扩展来兼容,通过两者对比能总结出以下区别:

GIF:

  • 最多支持 8 位 256 色,色阶过渡糟糕,图片具有颗粒感

  • 不支持 Alpha 透明通道,边缘有杂边

APNG:

  • 支持 24 位真彩色图片

  • 支持 8 位 Alpha 透明通道

  • 向下兼容 PNG

2、图片体积

如果你使用的浏览器不支持WebP,下面对比的 WebP 格式的图片将无法显示。

APNG 那些事

APNG 那些事

GIF = 43 920 bytes

APNG = 34 210 bytes

APNG 那些事

APNG 那些事

WebP = 41 064 bytes

Lossy WebP = 73 774 bytes

APNG 那些事

APNG 那些事

GIF = 43 132 bytes

APNG = 30 823 bytes

APNG 那些事

APNG 那些事

WebP = 55 968 bytes

Lossy WebP = 114 518 bytes

APNG 那些事

APNG 那些事

GIF = 200 700 bytes

APNG = 168 411 bytes

APNG 那些事

APNG 那些事

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 的示意图。

APNG 那些事

  • acTL 块必须在第一个 IDAT 块之前,用于告诉解析器这是一个动画 PNG,包含动画帧总数和循环次数的信息

  • fcTL 块是每一帧都必须的,出现在 IDAT 或 fdAT 之前,包含顺序号、宽高、帧位置、延时等信息

  • fdAT 块与 IDAT 块有着相同的结构,除了 fcTL 中的顺序号

从图中可以发现第一帧与后面两帧不同,那是因为第一帧 APNG 文件存储的为一个正常的 PNG 数据块,对于不支持 APNG 的浏览器或软件,只会显示 APNG 文件的第一帧,忽略后面附加的动画块,这也是为什么 APNG 能向下兼容 PNG 的原因。

APNG 帧间优化

假设使用一个 4 帧图片合成 APNG

APNG 那些事

APNG 会通过算法计算帧之间的差异,只存储帧之前的差异,而不是存储全帧。

APNG 那些事

通过 TweakPNG 软件观察 IDAT 图像数据块和 fdAT 帧数据块的大小,可以明显的看出来存储全帧与差异帧的区别,使得 APNG 文件大小有显著的减少。

APNG 那些事

为什么没有普及?

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 那些事

    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

APNG 那些事

Mac客户端 - APNGb

APNG 那些事

功能说明:

  • 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 那些事

APNG support in IE : Votes

APNG 那些事

感谢你的阅读。

参考资料

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

感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室

APNG 那些事

本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这