全面掌握移動端主流圖片格式的特點、性能、調優等

libbpg 目前並沒有針對 ARM NEON 做優化,所以其在移動端的性能表現一般。下面是 iPhone 6 上的性能測試:

全面掌握移動端主流圖片格式的特點、性能、調優等

由於 bpg 編碼時間太長,我並沒有將數據放到表格裡。可以看到相同質量下,BPG 的解碼速度還是差 JPEG 太多,大約慢了 3~5 倍。目前來說,BPG 適用於那些對流量非常敏感,但對解碼時間不敏感的地方。從網上的新聞來看,手機淘寶和手機QQ都已經有所嘗試,但不清楚他們是否對 BPG 解碼進行了優化。

7、動態圖片的編碼與解碼

動圖在網絡上非常受歡迎,它近似視頻,但通常實現簡單、文件體積小,應用範圍非常廣泛。動圖的始祖是 GIF,它自 Windows 1.0 時代就在互聯網上流行開來,直到今天仍然難以被其他格式取代。儘管它非常古老,但其所用的原理和今天幾種新興格式幾乎一樣。

下面是一張 GIF 格式的 QQ 大表情:

全面掌握移動端主流圖片格式的特點、性能、調優等

這張表情由 6 幅靜態圖構成,每幅圖片有一定的存活時間,連貫播放就形成了動畫:

全面掌握移動端主流圖片格式的特點、性能、調優等

這幾張圖中,大部分內容是相近的,為了壓縮文件體積,通常動圖格式都支持一些特殊的方式對相似圖片進行裁剪,只保留前後幀不同的部分(如下圖所示):

全面掌握移動端主流圖片格式的特點、性能、調優等

在解碼動圖時,解碼器通常採用所謂“畫布模式”進行渲染。想象一下:播放的區域是一張畫布,第一幀播放前先把畫布清空,然後完整的繪製上第一幀圖;播放第二幀時,不再清空畫布,而是隻把和第一幀不同的區域覆蓋到畫布上,就像油畫的創作那樣。

像這樣的第一幀就被稱為關鍵幀(即 I 幀,幀內編碼幀),而後續的那些通過補償計算得到的幀被稱為預測編碼幀(P幀)。一個壓縮的比較好的動圖內,通常只有少量的關鍵幀,而其餘都是預測編碼幀;一個較差的壓縮工具製作的動圖內,則基本都是關鍵幀。不同的動圖壓縮工具通常能得到不同的結果。

除此之外,動圖格式通常有更為詳細的參數控制每一幀的繪製過程,下面是 GIF/APNG/WebP 通用的幾個參數。

Disposal Method (清除方式) :

Do Not Dispose:把當前幀增量繪製到畫布上,不清空畫布;

Restore to Background:繪製當前幀之前,先把畫布清空為默認背景色;

Restore to Previous:繪製下一幀前,把先把畫布恢復為當前幀的前一幀。

Blend Mode (混合模式) :

Blend None: 繪製時,全部通道(包含Alpha通道)都會覆蓋到畫布,相當於繪製前先清空畫布的指定區域;

Blend over:繪製時,Alpha 通道會被合成到畫布,即通常情況下兩張圖片重疊的效果。

上面這些技術,就是常見動圖格式的基礎了,下面分別介紹一下不同動圖格式的特點。

7.1 GIF

GIF 缺陷非常明顯:

它通常只支持 256 色索引顏色,這導致它只能通過抖動、差值等方式模擬較多豐富的顏色;

它的 Alpha 通道只有 1 bit,這意味著一個像素只能是完全透明或者完全不透明。

全面掌握移動端主流圖片格式的特點、性能、調優等

上面這是騰訊博客裡的一張演示圖,可以看到 GIF 由於 Alpha 通道的問題,產生了嚴重的“毛邊”現象。

目前通常的解決方案是在圖片的邊緣加一圈白邊,以減輕這種視覺效果:

全面掌握移動端主流圖片格式的特點、性能、調優等

可以仔細觀察一下 QQ、微信等 App 裡面的動畫表情,幾乎每個表情都被一圈白邊所環繞,不得不說是一種很無奈的解決方案。

GIF 的製作工具有很多,但效果好、壓縮比高的工具非常少。對於已經制作好的 GIF 來說,用 imagemagick 處理一下可以把文件體積壓縮不少。如果需要將視頻轉為 GIF,Cinemagraph Pro 是個不錯的傻瓜化工具。文章《使用 FFmpeg 處理高質量 GIF 圖片》介紹瞭如何用 ffmpeg 壓縮 GIF,雖然參數調節有點麻煩,但效果非常理想。

下面是沒有經過優化的 GIF 和經過 ffmpeg 優化編碼的 GIF,可以看到差距非常大:

全面掌握移動端主流圖片格式的特點、性能、調優等

全面掌握移動端主流圖片格式的特點、性能、調優等

7.2 APNG

APNG 目前並沒有被 PNG 官方所接受,所以 libpng 並不能直接解碼 APNG。但由於 APNG 只是基於 PNG 的一個簡單擴展,所以在已經支持 PNG 的平臺上,可以很輕鬆的用少量代碼實現 APNG 的編解碼。Chromium 為了支持 APNG 播放,只增加了不到 600 行代碼 ,我自己也用大概 500 行 C 代碼實現了一個簡單的 APNG 編解碼工具。另外,在支持 canvas 的瀏覽器上,可以用 apng-canvas 直接顯示 APNG 動畫。APNG 壓縮最好的工具目前是 apngasm,大部分圖形化工具比如騰訊的 iSparta 都是基於這個工具開發的。

就目前而言, APNG 是 GIF 最好的替代了:實現簡單,可用範圍廣,壓縮比不錯,顯示效果好。

7.3 WebP

WebP 在 2010 年 發佈時並沒有支持動圖。2012 年 libwebp v0.2 的時候,Google 才開始嘗試支持動畫,但其實現有很多問題,性能也非常差,以至於 Chrome 團隊一直都沒有接受。直到 2013 年,libwebp v0.4 時,動畫格式才穩定下來才被 Chrome 所接受。

WebP 動圖實際上是把多個單幀 WebP 數據簡單打包到一個文件內,而並不是由單幀 WebP 擴展而來,以至於動圖格式並不能向上兼容靜態圖。如果要支持動圖,首先在編譯 libwebp 時需要加上 demux 模塊,解碼 WebP 時需要先用 WebPDemuxer 嘗試拆包,之後再把拆出來的單幀用 WebPDecode 解碼。為了方便編譯,我寫了個腳本用於打包 iOS 的靜態庫,加入了 mux 和 demux 模塊。

Google 提供了兩個簡單的命令行工具用於製作動圖:gif2webp 能把 GIF 轉換為 WebP, webpmux 能把多個 WebP 圖片打包為動態圖,並且有著很多參數可以調節。這兩個工具對相近幀的壓縮並不太理想,以至於有的情況下壓縮比還不如 APNG,但除此以外也沒有其他什麼更好的工具可以用了 (update: 在最近的 libwebp v0.6.0 中, Google 新提供了一個 img2webp 命令專門用於製作動圖的,效果不錯)。

7.4 BPG

BPG 本身是基於 HEVC (H.265) 視頻編碼的,其最開始設計時就考慮到了動圖的實現。由於它充分利用了 HEVC 的高壓縮比和視頻編碼的特性,其動圖壓縮比遠超其他格式。這裡和這裡有幾張 BPG 動圖示例,可以看到相同質量下 BPG 動圖只有 APNG/WebP/GIF 幾十分之一的大小。

我在這裡寫了個簡單的利用 libbpg 解碼動圖的方法,如有需要可以參考下。

8、動圖性能對比

我把下面這張 GIF 分別轉為 WebP、APNG、BPG 動圖,並在 iPhone 6 上對其所有幀進行解碼。

全面掌握移動端主流圖片格式的特點、性能、調優等

評測結果如下:

全面掌握移動端主流圖片格式的特點、性能、調優等

APNG 在文件體積上比 GIF 略有優勢,解碼時間相差不多。WebP 在體積和解碼時間上都具有較大的優勢。BPG 在體積上優勢最大,但解碼時間也最長。這麼看來,APNG 和 WebP 都是不錯的選擇,而 BPG 還有待性能優化。

最後做一個小廣告:

如果你是 iOS 平臺的開發者,可以試試我開發的 YYWebImage,它支持 APNG、WebP、GIF 動圖的異步加載與播放、編碼與解碼,支持漸進式圖像加載,可以替代 SDWebImage、PINRemoteImage、FLAnimatedImage 等開源庫。

附錄:更多移動端即時通訊應用開發文章

《移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”》

《移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結》

《從客戶端的角度來談談移動端IM的消息可靠性和送達機制》

《現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障》

《騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路》

《小白必讀:閒話HTTP短連接中的Session和Token》

《IM開發基礎知識補課:正確理解前置HTTP SSO單點登陸接口的原理》

《移動端IM中大規模群消息的推送如何保證效率、實時性?》

《移動端IM開發需要面對的技術問題》

《開發IM是自己設計協議用字節流好還是字符流好?》

《請問有人知道語音留言聊天的主流實現方式嗎?》

《IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞》

《IM消息送達保證機制實現(二):保證離線消息的可靠投遞》

《如何保證IM實時消息的“時序性”與“一致性”?》

《一個低成本確保IM消息時序的方法探討》

《IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?》

《IM群聊消息如此複雜,如何保證不丟不重?》

《談談移動端 IM 開發中登錄請求的優化》

《移動端IM登錄時拉取數據如何作到省流量?》

《淺談移動端IM的多點登陸和消息漫遊原理》

《完全自已開發的IM該如何設計“失敗重試”機制?》

《通俗易懂:基於集群的移動端IM接入層負載均衡方案分享》

《微信對網絡影響的技術試驗及分析(論文全文)》

《即時通訊系統的原理、技術和應用(技術論文)》

《開源IM工程“蘑菇街TeamTalk”的現狀:一場有始無終的開源秀》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)》

《騰訊原創分享(一):如何大幅提升移動網絡下手機QQ的圖片傳輸速度和成功率》

《騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)》

《騰訊原創分享(三):如何大幅壓縮移動網絡下APP的流量消耗(下篇)》

《如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源》

《基於社交網絡的Yelp是如何實現海量用戶圖片的無損壓縮的?》

《騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(圖片壓縮篇)》

《騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(音視頻技術篇)》

《為什麼說即時通訊社交APP創業就是一個坑?》

《字符編碼那點事:快速理解ASCII、Unicode、GBK和UTF-8》

《深入學習移動端主流圖片格式的特點、性能、調優等》

>> 更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-1802-1-1.html)


分享到:


相關文章: