圖片通常是移動(dòng)端流量耗費(fèi)最多的部分救斑,并且占據(jù)著重要的視覺(jué)空間。合理的圖片格式選用和優(yōu)化可以為你節(jié)省帶寬真屯、提升視覺(jué)效果脸候。在這篇文章里我會(huì)分析一下目前主流和新興的幾種圖片格式的特點(diǎn)、性能分析绑蔫、參數(shù)調(diào)優(yōu)运沦,以及相關(guān)開(kāi)源庫(kù)的選擇。
幾種圖片格式的簡(jiǎn)介
首先談一下大家耳熟能詳?shù)膸追N老牌的圖片格式吧:
JPEG是目前最常見(jiàn)的圖片格式配深,它誕生于 1992 年茶袒,是一個(gè)很古老的格式。它只支持有損壓縮凉馆,其壓縮算法可以精確控制壓縮比薪寓,以圖像質(zhì)量換得存儲(chǔ)空間亡资。由于它太過(guò)常見(jiàn),以至于許多移動(dòng)設(shè)備的 CPU 都支持針對(duì)它的硬編碼與硬解碼向叉。
PNG誕生在 1995 年锥腻,比 JPEG 晚幾年。它本身的設(shè)計(jì)目的是替代 GIF 格式母谎,所以它與 GIF 有更多相似的地方瘦黑。PNG 只支持無(wú)損壓縮,所以它的壓縮比是有上限的奇唤。相對(duì)于 JPEG 和 GIF 來(lái)說(shuō)幸斥,它最大的優(yōu)勢(shì)在于支持完整的透明通道。
GIF誕生于 1987 年咬扇,隨著初代互聯(lián)網(wǎng)流行開(kāi)來(lái)甲葬。它有很多缺點(diǎn),比如通常情況下只支持 256 種顏色懈贺、透明通道只有 1 bit经窖、文件壓縮比不高。它唯一的優(yōu)勢(shì)就是支持多幀動(dòng)畫(huà)梭灿,憑借這個(gè)特性画侣,它得以從 Windows 1.0 時(shí)代流行至今,而且仍然大受歡迎堡妒。
在上面這些圖片格式誕生后配乱,也有不少公司或團(tuán)體嘗試對(duì)他們進(jìn)行改進(jìn),或者創(chuàng)造其他更加優(yōu)秀的圖片格式皮迟,比如 JPEG 小組的 JPEG 2000搬泥、微軟的 JPEG-XR、Google 的 WebP万栅、個(gè)人開(kāi)發(fā)者發(fā)布的 BPG、FLIF 等西疤。它們相對(duì)于老牌的那幾個(gè)圖片格式來(lái)說(shuō)有了很大的進(jìn)步烦粒,但出于各種各樣的原因,只有少數(shù)幾個(gè)格式能夠流行開(kāi)來(lái)代赁。下面三種就是目前實(shí)力比較強(qiáng)的新興格式了:
APNG是 Mozilla 在 2008 年發(fā)布的一種圖片格式扰她,旨在替換掉畫(huà)質(zhì)低劣的 GIF 動(dòng)畫(huà)。它實(shí)際上只是相當(dāng)于 PNG 格式的一個(gè)擴(kuò)展芭碍,所以 Mozilla 一直想把它合并到 PNG 標(biāo)準(zhǔn)里面去徒役。然而 PNG 開(kāi)發(fā)組并沒(méi)有接受 APNG 這個(gè)擴(kuò)展,而是一直在推進(jìn)它自己的 MNG 動(dòng)圖格式窖壕。MNG 格式過(guò)于復(fù)雜以至于并沒(méi)有什么系統(tǒng)或?yàn)g覽器支持忧勿,而 APNG 格式由于簡(jiǎn)單容易實(shí)現(xiàn)杉女,目前已經(jīng)漸漸流行開(kāi)來(lái)。Mozilla 自己的 Firefox 首先支持了 APNG鸳吸,隨后蘋(píng)果的 Safari 也開(kāi)始有了支持熏挎, Chrome 目前也已經(jīng)嘗試開(kāi)始支持 ,可以說(shuō)未來(lái)前景很好晌砾。
WebP是 Google 在 2010 年發(fā)布的圖片格式坎拐,希望以更高的壓縮比替代 JPEG。它用 VP8 視頻幀內(nèi)編碼作為其算法基礎(chǔ)养匈,取得了不錯(cuò)的壓縮效果哼勇。它支持有損和無(wú)損壓縮、支持完整的透明通道呕乎、也支持多幀動(dòng)畫(huà)积担,并且沒(méi)有版權(quán)問(wèn)題,是一種非常理想的圖片格式楣嘁。借由 Google 在網(wǎng)絡(luò)世界的影響力磅轻,WebP 在幾年的時(shí)間內(nèi)已經(jīng)得到了廣泛的應(yīng)用≈鹦椋看看你手機(jī)里的 App:微博聋溜、微信、QQ叭爱、淘寶撮躁、網(wǎng)易新聞等等,每個(gè) App 里都有 WebP 的身影买雾。Facebook 則更進(jìn)一步把曼,用 WebP 來(lái)顯示聊天界面的貼紙動(dòng)畫(huà)。
BPG是著名程序員 Fabrice Bellard 在去年 (2014年) 發(fā)布的一款超高壓縮比的圖片格式漓穿。這個(gè)程序員有些人可能感覺(jué)面生嗤军,但說(shuō)起他的作品 FFmpeg、QEMU 大家想必是都知道的晃危。BPG 使用 HEVC (即 H.265) 幀內(nèi)編碼作為其算法基礎(chǔ)叙赚,就這點(diǎn)而言,它毋庸置疑是當(dāng)下最為先進(jìn)的圖片壓縮格式僚饭。相對(duì)于 JP2震叮、JPEG-XR、WebP 來(lái)說(shuō)鳍鸵,同等體積下 BPG 能提供更高的圖像質(zhì)量苇瓣。另外,得益于它本身基于視頻編碼算法的特性偿乖,它能以非常小的文件體積保存多幀動(dòng)畫(huà)击罪。 Fabrice Bellard 聰明的地方在于哲嘲,他知道自己一個(gè)人無(wú)法得到各大瀏覽器廠商的支持,所以他還特地開(kāi)發(fā)了 Javascript 版的解碼器外邓,任何瀏覽器只要加載了這個(gè) 76KB 大小的 JS 文件撤蚊,就可以直接顯示 BPG 格式的圖片了。目前阻礙它流行的原因就是 HEVC 的版權(quán)問(wèn)題和它較長(zhǎng)的編碼解碼時(shí)間损话。盡管這個(gè)圖片格式才剛剛發(fā)布一年侦啸,但已經(jīng)有不少?gòu)S子開(kāi)始試用了,比如阿里和騰訊丧枪。
移動(dòng)端圖片類型的支持情況
目前主流的移動(dòng)端對(duì)圖片格式的支持情況如何呢光涂?我們分別來(lái)看一下 Android 和 iOS 目前的圖片編解碼架構(gòu)吧:
Android 的圖片編碼解碼是由 Skia 圖形庫(kù)負(fù)責(zé)的,Skia 通過(guò)掛接第三方開(kāi)源庫(kù)實(shí)現(xiàn)了常見(jiàn)的圖片格式的編解碼支持拧烦。目前來(lái)說(shuō)忘闻,Android 原生支持的格式只有 JPEG、PNG恋博、GIF齐佳、BMP 和 WebP (Android 4.0 加入),在上層能直接調(diào)用的編碼方式也只有 JPEG债沮、PNG炼吴、WebP 這三種。目前來(lái)說(shuō) Android 還不支持直接的動(dòng)圖編解碼。
iOS 底層是用 ImageIO.framework 實(shí)現(xiàn)的圖片編解碼。目前 iOS 原生支持的格式有:JPEG怜浅、JPEG2000、PNG童芹、GIF、BMP鲤拿、ICO假褪、TIFF、PICT近顷,自 iOS 8.0 起生音,ImageIO 又加入了 APNG、SVG幕庐、RAW 格式的支持久锥。在上層家淤,開(kāi)發(fā)者可以直接調(diào)用 ImageIO 對(duì)上面這些圖片格式進(jìn)行編碼和解碼异剥。對(duì)于動(dòng)圖來(lái)說(shuō),開(kāi)發(fā)者可以解碼動(dòng)畫(huà) GIF 和 APNG絮重、可以編碼動(dòng)畫(huà) GIF冤寿。
兩個(gè)平臺(tái)在導(dǎo)入第三方編解碼庫(kù)時(shí)歹苦,都多少對(duì)他們進(jìn)行了一些修改,比如 Android 對(duì) libjpeg 等進(jìn)行的調(diào)整以更好的控制內(nèi)存督怜,iOS 對(duì) libpng 進(jìn)行了修改以支持 APNG殴瘦,并增加了多線程編解碼的特性。除此之外号杠,iOS 專門(mén)針對(duì) JPEG 的編解碼開(kāi)發(fā)了 AppleJPEG.framework蚪腋,實(shí)現(xiàn)了性能更高的硬編碼和硬解碼,只有當(dāng)硬編碼解碼失敗時(shí)姨蟋,libjpeg 才會(huì)被用到屉凯。
靜態(tài)圖片的編碼與解碼
由于我目前主要是做 iOS 開(kāi)發(fā),所以下面的性能評(píng)測(cè)都是基于 iPhone 的眼溶,主要測(cè)試代碼可以在這里看到悠砚。
JPEG
目前比較知名的 JPEG 庫(kù)有以下三個(gè):
libjpeg:開(kāi)發(fā)時(shí)間最早,使用最廣泛的 JPEG 庫(kù)堂飞。由于 JPEG 標(biāo)準(zhǔn)過(guò)于復(fù)雜和模糊灌旧,并沒(méi)有其他人去實(shí)現(xiàn),所以這個(gè)庫(kù)是 JPEG 的事實(shí)標(biāo)準(zhǔn)绰筛。
libjpeg-turbo:一個(gè)致力于提升編解碼速度的 JPEG 庫(kù)枢泰。它基于 libjpeg 進(jìn)行了改造,用 SIMD 指令集 (MMX别智、SSE2宗苍、NEON) 重寫(xiě)了部分代碼,官網(wǎng)稱相對(duì)于 libjpeg 有 2 到 4 倍的性能提升薄榛。
MozJPEG: 一個(gè)致力于提升壓縮比的 JPEG 庫(kù)讳窟。它是 Mozilla 在 2014 年發(fā)布的基于 libjpeg-turbo 進(jìn)行改造的庫(kù),相對(duì)于 libjpeg 有 5% ~ 15%的壓縮比提升敞恋,但相應(yīng)的其編碼速度也慢了很多丽啡。
除了上面這三個(gè)庫(kù),蘋(píng)果自己也開(kāi)發(fā)了一個(gè) AppleJPEG硬猫,但并沒(méi)有開(kāi)源补箍。其調(diào)用了芯片提供的 DSP 硬編碼和硬解碼的功能。雖然它不如上面這三個(gè)庫(kù)功能完善啸蜜,但其性能非常高坑雅。在我的測(cè)試中,其編解碼速度通常是 libjpeg-turbo 的 1~2 倍衬横」粒可惜的是,目前開(kāi)發(fā)者并不能直接訪問(wèn)這個(gè)庫(kù)蜂林。
蘋(píng)果在自己的相冊(cè) Demo 中提供的 quality 的默認(rèn)值是 0.9遥诉,在這個(gè)值附近拇泣,圖像質(zhì)量和體積、編碼解碼時(shí)間之間都能取得不錯(cuò)的平衡矮锈。
PNG
相對(duì)于 JPEG 來(lái)說(shuō)霉翔,PNG 標(biāo)準(zhǔn)更為清晰和簡(jiǎn)單,因此有很多公司或個(gè)人都有自己的 PNG 編碼解碼實(shí)現(xiàn)苞笨。但目前使用最廣的還是 PNG 官方發(fā)布的libpng庫(kù)债朵。iOS 和 Android 底層都是調(diào)用這個(gè)庫(kù)實(shí)現(xiàn)的 PNG 編解碼。
在編解碼圖形類型(顏色少瀑凝、細(xì)節(jié)少)的圖片時(shí)葱弟,PNG 和 JPEG 差距并不大;但是對(duì)于照片類型(顏色和細(xì)節(jié)豐富)的圖片來(lái)說(shuō)猜丹,PNG 在文件體積芝加、編解碼速度上都差 JPEG 不少了。
和 JPEG 不同射窒,PNG 是無(wú)損壓縮藏杖,其并不能提供壓縮比的選項(xiàng),其壓縮比是有上限的脉顿。
pngcrush是 Xcode 自帶的 PNG 壓縮工具蝌麸,相對(duì)于設(shè)計(jì)師用 Photoshop 生成的圖片來(lái)說(shuō),它能取得不錯(cuò)的壓縮效果艾疟。ImageOptim則更進(jìn)一步来吩,對(duì)每張圖用多種縮算法進(jìn)行比對(duì),選擇壓縮比更高的結(jié)果蔽莱,進(jìn)一步縮小了文件體積弟疆。TinyPNG.com相對(duì)于其他工具來(lái)說(shuō),壓縮比高得不像話盗冷。它啟用了類似 GIF 那樣的顏色索引表對(duì) PNG 進(jìn)行壓縮怠苔,所以會(huì)導(dǎo)致顏色豐富的圖片丟失掉一部分細(xì)節(jié)。如果使用 TinyPNG 的話仪糖,最好在壓縮完成后讓設(shè)計(jì)師看一下顏色效果是否可以接受柑司。
WebP
WebP 標(biāo)準(zhǔn)是 Google 定制的,迄今為止也只有 Google 發(fā)布的libwebp實(shí)現(xiàn)了該的編解碼 锅劝。 所以這個(gè)庫(kù)也是該格式的事實(shí)標(biāo)準(zhǔn)攒驰。
WebP 編碼主要有幾個(gè)參數(shù):
lossless: YES:有損編碼 NO:無(wú)損編碼。WebP 主要優(yōu)勢(shì)在于有損編碼故爵,其無(wú)損編碼的性能和壓縮比表現(xiàn)一般玻粪。
quality: [0~100] 圖像質(zhì)量,0表示最差質(zhì)量,文件體積最小奶段,細(xì)節(jié)損失嚴(yán)重,100表示最高圖像質(zhì)量剥纷,文件體積較大痹籍。該參數(shù)只針對(duì)有損壓縮有明顯效果。Google 官方的建議是 75晦鞋,騰訊在對(duì) WebP 評(píng)測(cè)時(shí)給出的建議也是 75蹲缠。在這個(gè)值附近,WebP 能在壓縮比悠垛、圖像質(zhì)量上取得較好的平衡线定。
method: [0~6] 壓縮比,0表示快速壓縮确买,耗時(shí)短斤讥,壓縮質(zhì)量一般,6表示極限壓縮湾趾,耗時(shí)長(zhǎng)芭商,壓縮質(zhì)量好。該參數(shù)也只針對(duì)有損壓縮有明顯效果搀缠。調(diào)節(jié)該參數(shù)最高能帶來(lái) 20% ~ 40% 的更高壓縮比铛楣,但相應(yīng)的編碼時(shí)間會(huì)增加 5~20 倍。Google 推薦的值是 4艺普。
對(duì)于編碼無(wú)損圖片來(lái)說(shuō)簸州,quality=0, method=0~3 是相對(duì)來(lái)說(shuō)比較合適的參數(shù),能夠節(jié)省編碼時(shí)間歧譬,同時(shí)也有不錯(cuò)的壓縮比岸浑。無(wú)損編碼圖片,quality=75, method=2~4 是比較合適的參數(shù)瑰步,能在編碼時(shí)間助琐、圖片質(zhì)量、文件體積之間有著不錯(cuò)的平衡面氓。
WebP 解碼有三個(gè)參數(shù):
use_threads: 是否啟用 pthread 多線程解碼兵钮。該參數(shù)只對(duì)寬度大于 512 的有損圖片起作用。開(kāi)啟后內(nèi)部會(huì)用多線程解碼舌界,CPU 占用會(huì)更高掘譬,解碼時(shí)間平均能縮短 10%~20%。
bypass_filtering: 是否禁用濾波呻拌。該參數(shù)只對(duì)有損圖片起作用葱轩,開(kāi)啟后大約能縮短 5%~10% 的解碼時(shí)間,但會(huì)造成一些顏色過(guò)渡平滑的區(qū)域產(chǎn)生色帶(banding)。
no_fancy_upsampling: 是否禁用上采樣靴拱。該參數(shù)只對(duì)有損圖片起作用垃喊。在我的測(cè)試中,開(kāi)啟該參數(shù)后袜炕,解碼時(shí)間反而會(huì)增加 5~25%本谜,同時(shí)會(huì)造成一些圖像細(xì)節(jié)的丟失,線條邊緣會(huì)增加雜色偎窘,顯得不自然乌助。
通常情況下,這三個(gè)參數(shù)都設(shè)為 NO 即可陌知,如果要追求更高的解碼速度他托,則可以嘗試開(kāi)啟 use_threads 和 bypass_filtering 這兩個(gè)參數(shù)。而 no_fancy_upsampling 在任何情況下都沒(méi)必要開(kāi)啟仆葡。
對(duì)于簡(jiǎn)單的圖形類型的圖像(比如 App 內(nèi)的各種 UI 素材)赏参,WebP 無(wú)損壓縮的文件體積和解碼速度某些情況下已經(jīng)比 PNG 還要理想了,如果你想要對(duì) App 安裝包體積進(jìn)行優(yōu)化沿盅,可以嘗試一下 WebP登刺。
對(duì)于復(fù)雜的圖像(比如照片)來(lái)說(shuō),WebP 無(wú)損編碼表現(xiàn)并不好嗡呼,但有損編碼表現(xiàn)卻非常棒纸俭。相近質(zhì)量的圖片解碼速度 WebP 相距 JPEG 也已經(jīng)相差不大了,而文件壓縮比卻能提升不少南窗。
BPG
BPG 是目前已知最優(yōu)秀的有損壓縮格式了揍很,它能在相同質(zhì)量下比 JPEG 減少 50% 的體積。下面是經(jīng)典的 Lena 圖的對(duì)比万伤,你也可以在這里看到大量其他圖片的 BPG窒悔、JPEG、JPEG2000敌买、JPEG-XR简珠、WebP 壓縮效果的在線對(duì)比,效果非常明顯虹钮。
BPG 目前只有作者發(fā)布的libbpg可用聋庵。但作者基于 libbpg 編譯出了一個(gè) Javascript 解碼器,很大的擴(kuò)展了可用范圍芙粱。bpg 可以以無(wú)損和有損壓縮兩種方式進(jìn)行編碼祭玉,有損壓縮時(shí)可以用 quality 參數(shù)控制壓縮比,可選范圍為 0~51春畔,數(shù)值越大壓縮比越高脱货。通常來(lái)說(shuō)岛都,25 附近是一個(gè)不錯(cuò)的選擇,BPG 官方工具默認(rèn)值是 28振峻。
由于 bpg 編碼時(shí)間太長(zhǎng)臼疫,我并沒(méi)有將數(shù)據(jù)放到表格里】勖希可以看到相同質(zhì)量下烫堤,BPG 的解碼速度還是差 JPEG 太多,大約慢了 3~5 倍哈打。目前來(lái)說(shuō),BPG 適用于那些對(duì)流量非常敏感讯壶,但對(duì)解碼時(shí)間不敏感的地方料仗。從網(wǎng)上的新聞來(lái)看,手機(jī)淘寶和手機(jī)QQ都已經(jīng)有所嘗試伏蚊,但不清楚他們是否對(duì) BPG 解碼進(jìn)行了優(yōu)化立轧。
動(dòng)態(tài)圖片的編碼與解碼
動(dòng)圖在網(wǎng)絡(luò)上非常受歡迎,它近似視頻躏吊,但通常實(shí)現(xiàn)簡(jiǎn)單氛改、文件體積小,應(yīng)用范圍非常廣泛比伏。動(dòng)圖的始祖是 GIF胜卤,它自 Windows 1.0 時(shí)代就在互聯(lián)網(wǎng)上流行開(kāi)來(lái),直到今天仍然難以被其他格式取代赁项。盡管它非常古老葛躏,但其所用的原理和今天幾種新興格式幾乎一樣。
在解碼動(dòng)圖時(shí)悠菜,解碼器通常采用所謂"畫(huà)布模式"進(jìn)行渲染舰攒。想象一下:播放的區(qū)域是一張畫(huà)布,第一幀播放前先把畫(huà)布清空悔醋,然后完整的繪制上第一幀圖摩窃;播放第二幀時(shí),不再清空畫(huà)布芬骄,而是只把和第一幀不同的區(qū)域覆蓋到畫(huà)布上猾愿,就像油畫(huà)的創(chuàng)作那樣。
像這樣的第一幀就被稱為關(guān)鍵幀(即 I 幀账阻,幀內(nèi)編碼幀)匪蟀,而后續(xù)的那些通過(guò)補(bǔ)償計(jì)算得到的幀被稱為預(yù)測(cè)編碼幀(P幀)。一個(gè)壓縮的比較好的動(dòng)圖內(nèi)宰僧,通常只有少量的關(guān)鍵幀材彪,而其余都是預(yù)測(cè)編碼幀观挎;一個(gè)較差的壓縮工具制作的動(dòng)圖內(nèi),則基本都是關(guān)鍵幀段化。不同的動(dòng)圖壓縮工具通常能得到不同的結(jié)果嘁捷。
除此之外,動(dòng)圖格式通常有更為詳細(xì)的參數(shù)控制每一幀的繪制過(guò)程显熏,下面是 GIF/APNG/WebP 通用的幾個(gè)參數(shù):
Disposal Method (清除方式)
Do Not Dispose:把當(dāng)前幀增量繪制到畫(huà)布上雄嚣,不清空畫(huà)布。
Restore to Background:繪制當(dāng)前幀之前喘蟆,先把畫(huà)布清空為默認(rèn)背景色缓升。
Restore to Previous:繪制下一幀前,把先把畫(huà)布恢復(fù)為當(dāng)前幀的前一幀
Blend Mode (混合模式)
Blend None: 繪制時(shí)蕴轨,全部通道(包含Alpha通道)都會(huì)覆蓋到畫(huà)布港谊,相當(dāng)于繪制前先清空畫(huà)布的指定區(qū)域。
Blend over:繪制時(shí)橙弱,Alpha 通道會(huì)被合成到畫(huà)布歧寺,即通常情況下兩張圖片重疊的效果。
上面這些技術(shù)棘脐,就是常見(jiàn)動(dòng)圖格式的基礎(chǔ)了斜筐,下面分別介紹一下不同動(dòng)圖格式的特點(diǎn)。
GIF
GIF 缺陷非常明顯:它通常只支持 256 色索引顏色蛀缝,這導(dǎo)致它只能通過(guò)抖動(dòng)顷链、差值等方式模擬較多豐富的顏色;它的 Alpha 通道只有 1 bit屈梁,這意味著一個(gè)像素只能是完全透明或者完全不透明蕴潦。
GIF 的制作工具有很多,但效果好俘闯、壓縮比高的工具非常少潭苞。對(duì)于已經(jīng)制作好的 GIF 來(lái)說(shuō),用imagemagick處理一下可以把文件體積壓縮不少真朗。如果需要將視頻轉(zhuǎn)為 GIF此疹,Cinemagraph Pro是個(gè)不錯(cuò)的傻瓜化工具。這里有一篇文章介紹如何用 ffmpeg 壓縮 GIF遮婶,雖然參數(shù)調(diào)節(jié)有點(diǎn)麻煩蝗碎,但效果非常理想。
APNG
APNG 目前并沒(méi)有被 PNG 官方所接受旗扑,所以 libpng 并不能直接解碼 APNG蹦骑。但由于 APNG 只是基于 PNG 的一個(gè)簡(jiǎn)單擴(kuò)展,所以在已經(jīng)支持 PNG 的平臺(tái)上臀防,可以很輕松的用少量代碼實(shí)現(xiàn) APNG 的編解碼眠菇。Chromium 為了支持 APNG 播放边败,只增加了不到 600 行代碼,我自己也用大概 500 行 C 代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 APNG 編解碼工具捎废。另外笑窜,在支持 canvas 的瀏覽器上,可以用apng-canvas直接顯示 APNG 動(dòng)畫(huà)登疗。APNG 壓縮最好的工具目前是apngasm排截,大部分圖形化工具比如騰訊的iSparta都是基于這個(gè)工具開(kāi)發(fā)的。
就目前而言辐益, APNG 是 GIF 最好的替代了:實(shí)現(xiàn)簡(jiǎn)單断傲,可用范圍廣,壓縮比不錯(cuò)智政,顯示效果好认罩。
WebP
WebP 在 2010 年 發(fā)布時(shí)并沒(méi)有支持動(dòng)圖。2012 年 libwebp v0.2 的時(shí)候女仰,Google 才開(kāi)始嘗試支持動(dòng)畫(huà)猜年,但其實(shí)現(xiàn)有很多問(wèn)題抡锈,性能也非常差疾忍,以至于 Chrome 團(tuán)隊(duì)一直都沒(méi)有接受。直到 2013 年床三,libwebp v0.4 時(shí)一罩,動(dòng)畫(huà)格式才穩(wěn)定下來(lái)才被 Chrome 所接受。
WebP 動(dòng)圖實(shí)際上是把多個(gè)單幀 WebP 數(shù)據(jù)簡(jiǎn)單打包到一個(gè)文件內(nèi)撇簿,而并不是由單幀 WebP 擴(kuò)展而來(lái)聂渊,以至于動(dòng)圖格式并不能向上兼容靜態(tài)圖。如果要支持動(dòng)圖四瘫,首先在編譯 libwebp 時(shí)需要加上 demux 模塊汉嗽,解碼 WebP 時(shí)需要先用 WebPDemuxer 嘗試拆包,之后再把拆出來(lái)的單幀用 WebPDecode 解碼找蜜。為了方便編譯饼暑,我寫(xiě)了個(gè)腳本用于打包 iOS 的靜態(tài)庫(kù),加入了 mux 和 demux 模塊弓叛。
Google 提供了兩個(gè)簡(jiǎn)單的命令行工具用于制作動(dòng)圖:gif2webp 能把 GIF 轉(zhuǎn)換為 WebP, webpmux 能把多個(gè) WebP 圖片打包為動(dòng)態(tài)圖诚纸,并且有著很多參數(shù)可以調(diào)節(jié)撰筷。這兩個(gè)工具對(duì)相近幀的壓縮并不太理想抬闯,以至于有的情況下壓縮比還不如 APNG平委,但除此以外也沒(méi)有其他什么更好的工具可以用了。
BPG
BPG 本身是基于 HEVC (H.265) 視頻編碼的馏艾,其最開(kāi)始設(shè)計(jì)時(shí)就考慮到了動(dòng)圖的實(shí)現(xiàn)。由于它充分利用了 HEVC 的高壓縮比和視頻編碼的特性,其動(dòng)圖壓縮比遠(yuǎn)超其他格式房资。這里和這里有幾張 BPG 動(dòng)圖示例蜕劝,可以看到相同質(zhì)量下 BPG 動(dòng)圖只有 APNG/WebP/GIF 幾十分之一的大小。
我在這里寫(xiě)了個(gè)簡(jiǎn)單的利用 libbpg 解碼動(dòng)圖的方法轰异,如有需要可以參考下岖沛。
APNG 在文件體積上比 GIF 略有優(yōu)勢(shì),解碼時(shí)間相差不多搭独。WebP 在體積和解碼時(shí)間上都具有較大的優(yōu)勢(shì)婴削。BPG 在體積上優(yōu)勢(shì)最大,但解碼時(shí)間也最長(zhǎng)牙肝。這么看來(lái)唉俗,APNG 和 WebP 都是不錯(cuò)的選擇,而 BPG 還有待性能優(yōu)化惊奇。
最后做一個(gè)小廣告:如果你是 iOS 平臺(tái)的開(kāi)發(fā)者互躬,可以試試我開(kāi)發(fā)的YYWebImage,它支持 APNG颂郎、WebP吼渡、GIF 動(dòng)圖的異步加載與播放、編碼與解碼乓序,支持漸進(jìn)式圖像加載寺酪,可以替代 SDWebImage坎背、PINRemoteImage、FLAnimatedImage 等開(kāi)源庫(kù)寄雀。
原文閱讀