簡介
APNG( ),基于PNG( )規范的擴展動畫文件格式。APNG文件類似于GIF文件,但是支持了GIF不支持的24-bit圖像以及透明通道。另外,基于GIF生成的APNG尺寸往往小于GIF。因此,APNG是一種可以用來代替GIF的文件格式,因為你可以選擇比GIF更好的效果或者選擇比GIF更小的文件尺寸。
本文的主要目的是推薦前端同學將當前的GIF格式替換到APNG格式。如果你尚未了解APNG格式,建議你花5分鐘時間讀完章節即可。如果你對APNG格式細節感興趣也可以多花一些時間讀完全文。
幾種動畫格式的對比
目前最流行的動畫格式是GIF格式,除此之外,本文提到的APNG格式,以及WebP格式都是比較常見的動畫格式。本文建議使用的動畫格式是APNG格式。
尺寸
相同圖像效果下:WebP < APNG < GIF
說明:理論上來說WebP的壓縮率是最高的,但是經過實際測試發現如果同樣是從GIF轉換過來的圖片格式,APNG的文件尺寸往往小于GIF的文件尺寸。
效果
從圖像質量的維度來看,WebP = APNG > GIF。因為WebP和APNG都可以提供24-bit圖像已經透明通道,因此這兩種格式的動畫的圖像質量都要遠遠好于GIF格式。
性能
從加載時間的維度來看,WebP > APNG > GIF。由于APNG圖片的第一幀是一張完整的PNG圖片,因此WebP格式的首圖像顯示時間要小于APNG格式的首幀顯示時間,點擊這里可以查看一個關于APNG和WebP的文件尺寸,加載時間的對比說明。另外,UC的開發者工具,Trace工具也可以直觀的查看到不同格式的動畫顯示時間,CPU占用率。
支持情況
GIF > APNG > WebP
GIF毫無疑問是支持的最好的,全平臺支持。
APNG目前在和最新版本的 for 上支持,的系統尚未支持。
WebP在iOS上尚未支持。
安卓版的UC內核,WebP的動畫格式已經支持,APNG格式支持的開發工作已經完成,不久后會正式上線。
APNG實戰
前面簡要的介紹了APNG。接下來我們會通過實例,使用GIF文件生成APNG格式的文件進行比較。
壓縮工具
本文選用了作為壓縮工具,版本是1.9,工作環境是。工具可以從這里下載,使用方法如下:
anim.gif anim.png
-z0:zlib壓縮
-z1:7zip壓縮(缺省)
-z2:壓縮
-i##:7zip和的循環次數(缺省為15)
實例
選擇了天貓超市首頁的三張gif圖片做測試,原始圖片如下:
圖1:
圖2:
圖3:
壓縮命令如下:
例如使用壓縮方案,循環100次壓縮gif3.gif文件,生成png3-z2-100.png
實驗結果如下:
實驗結論:
壓縮后的效果如下(下例使用壓縮,循環15次):
APNG(本來是APNG格式的圖片,被知乎轉碼了)
GIF
另外,不同的壓縮方式,不同的壓縮循環次數目前沒有對圖片的顯示有明顯的影響(包括CPU使用率,內存等),不過這個結論還需要繼續觀察。
視頻轉APNG
大家都知道可以將視頻轉為GIF,實際上同樣也支持APNG的編碼。
ffmpeg -i your.mp4 -plays 0 out.apng
轉碼支持各種參數。沒有任何參數的情況下,生成的apng格式文件的尺寸很感人。
點擊這里可以看到同樣的視頻分別轉碼APNG和GIF的對比效果。
兼容方案
UC內核近期更新后會支持APNG格式動畫,那么對于尚未更新到最新UC版本內核(例如早期版本的U4 SDK,系統等)的應用應該如何做兼容處理?回退到GIF動畫么?
答案是不必。apng-是一個JS版本的兼容方案。如果你的應用不支持APNG格式時可以使用這個庫做兼容方案。
如何檢測你的應用是否支持APNG格式
示例代碼
/*
* apng-detect.js
* 2010-06-13
* By Eli Grey, http://eligrey.com
*
* Detects if a browser supports the APNG format and sets a
* global `APNG` boolean indicating if the browser supports APNG.
*
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
(function() {
"use strict";
var apngTest = new Image(),
ctx = document.createElement("canvas").getContext("2d");
apngTest.onload = function () {
ctx.drawImage(apngTest, 0, 0);
self.APNG = ( ctx.getImageData(0, 0, 1, 1).data[3] === 0 );
};
apngTest.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==";
// frame 1 (skipped on apng-supporting browsers): [0, 0, 0, 255]
// frame 2: [0, 0, 0, 0]
}());
APNG表示你的應用是否支持APNG格式。代碼來自這里。原理,不支持APNG的應用只能繪制第一幀,支持APNG的應用可以繪制到第二幀,判斷的數據是否為第二幀數據即可以判斷應用是否支持APNG。
兼容方案示例
從這里下載最新的(其實最后更新也是2年前了)庫,頁端加載"app-.min.js"即擁有純JS繪制APNG動畫的能力。
示例代碼
var img1 = document.getElementById("z1")
img1.src = "./resources/test.png"
img1.onload = function() {
APNG.animateImage(img1);
}
圖片加載成功后,調用APNG.繪制的img元素。
通過trace工具查看,使用兼容方案繪制APNG動畫不會有明顯的CPU占用率提升的現象。實際使用過程中也未發現有明顯卡頓,掉幀等現象。另外,該JS庫的尺寸為15K,因此當頁面中原始GIF文件的總尺寸超過100K時,即使你的應用不支持APNG解碼如何判斷解碼器支持24bit,使用該JS兼容方案也能獲得收益。
關于APNG的一些技術細節
前面章節介紹了APNG的優勢(尺寸,效果等),下面章節主要是介紹APNG本身的一些技術細節,跳過后面的章節并不影響你使用APNG。
PNG結構
一個標準的PNG格式由PNG簽名(8 bytes)和多個PNG塊構成。一個PNG塊由4部分構成:塊長度(4 bytes),塊類型(4 bytes),塊數據以及CRC校驗(4 bytes)。
最簡單的PNG格式由3種PNG塊構成,IHDR(圖像頭)塊,一個或多個IDAT(圖像數據)塊和IEND(圖像結尾)塊。
APNG結構
PNG格式在設計之初就考慮到擴展性,解碼器在解碼PNG格式或基于PNG擴展的格式的文件時,只需要解碼支持的PNG塊如何判斷解碼器支持24bit,忽略尚未支持的PNG塊。因此一個僅支持PNG格式的解碼器解碼APNG文件時,識別到APNG文件中的PNG簽名,IHDR塊,IDAT塊,IEND塊也可以將缺省圖片解碼出來。因此APNG格式是向后兼容的。
acTL結構
IDAT塊之前一定有acTL塊
fcTL結構
IDAT塊或fdAT塊之前一定有fcTL塊
GIF文件尺寸比較
APNG和GIF都是增量渲染,即僅渲染幀變化的區域,這樣可以降低文件尺寸。那么為什么同樣的動畫文件,APNG尺寸小于GIF?
以下是相同的動畫內容不同文件格式的數據解析,顯示了每一幀在文件內所占用的尺寸:
上圖為GIF文件解析結果,下圖為APNG文件解析結果。
GIF文件的壓縮方式導致它每一幀都會大于同等質量的APNG文件。另外,GIF每一幀的額外數據尺寸大約為,而APNG每一幀的額外數據尺寸大約為。因此,幀數越大GIF文件的尺寸也會越大。
參考文檔
APNG Wiki
APNG那些事
APNG規范