Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          1、引言

          圖片通常是移動(dòng)端應(yīng)用流量耗費(fèi)最多的部分,并且占據(jù)著重要的視覺(jué)空間。以大家最常用的即時(shí)通訊IM應(yīng)用為例,應(yīng)用中存在大量的圖片數(shù)據(jù)往來(lái)(比如圖片消息、用戶相冊(cè)、用戶頭像等等)。合理的圖片格式選用和優(yōu)化不僅能減小圖片傳遞過(guò)程中的數(shù)據(jù)量、提升視覺(jué)效果,還能顯著降低服務(wù)端的帶寬、計(jì)算資源等基礎(chǔ)設(shè)施成本,一舉多得。

          本文我們一起全面分析學(xué)習(xí)目前主流和新興的幾種圖片格式的特點(diǎn)、性能、調(diào)優(yōu)等,以及相關(guān)開源庫(kù)的選擇,希望能為您的移動(dòng)端應(yīng)用(包括本社區(qū)主要討論的即時(shí)通訊應(yīng)用)中的圖片優(yōu)化帶來(lái)一些啟發(fā)。

          學(xué)習(xí)交流:

          - 即時(shí)通訊開發(fā)交流3群:185926912[推薦]

          - 移動(dòng)端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動(dòng)端IM

          (本文同步發(fā)布于:http://www.52im.net/thread-1802-1-1.html

          2、關(guān)于作者

          郭曜源:畢業(yè)于哈爾濱工程大學(xué),現(xiàn)為優(yōu)酷iOS開發(fā)工程師,是iOS上的熱門開源工程YYWebImageYYText等的作者,個(gè)人github地址:https://github.com/ibireme/

          3、相關(guān)文章

          騰訊技術(shù)分享:社交網(wǎng)絡(luò)圖片的帶寬壓縮技術(shù)演進(jìn)之路

          QQ音樂(lè)團(tuán)隊(duì)分享:Android中的圖片壓縮技術(shù)詳解(上篇)

          QQ音樂(lè)團(tuán)隊(duì)分享:Android中的圖片壓縮技術(shù)詳解(下篇)

          騰訊原創(chuàng)分享(一):如何大幅提升移動(dòng)網(wǎng)絡(luò)下手機(jī)QQ的圖片傳輸速度和成功率

          騰訊原創(chuàng)分享(二):如何大幅壓縮移動(dòng)網(wǎng)絡(luò)下APP的流量消耗(上篇)

          騰訊原創(chuàng)分享(三):如何大幅壓縮移動(dòng)網(wǎng)絡(luò)下APP的流量消耗(下篇)

          基于社交網(wǎng)絡(luò)的Yelp是如何實(shí)現(xiàn)海量用戶圖片的無(wú)損壓縮的?

          騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(圖片壓縮篇)

          4、認(rèn)識(shí)主流的圖片格式

          首先談一下大家耳熟能詳?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)流行開來(lái)。它有很多缺點(diǎn),比如通常情況下只支持 256 種顏色、透明通道只有 1 bit、文件壓縮比不高。它唯一的優(yōu)勢(shì)就是支持多幀動(dòng)畫,憑借這個(gè)特性,它得以從 Windows 1.0 時(shí)代流行至今,而且仍然大受歡迎。

          在上面這些圖片格式誕生后,也有不少公司或團(tuán)體嘗試對(duì)他們進(jìn)行改進(jìn),或者創(chuàng)造其他更加優(yōu)秀的圖片格式,比如 JPEG 小組的 JPEG 2000、微軟的 JPEG-XR、Google 的 WebP、個(gè)人開發(fā)者發(fā)布的 BPG、FLIF 等。它們相對(duì)于老牌的那幾個(gè)圖片格式來(lái)說(shuō)有了很大的進(jìn)步,但出于各種各樣的原因,只有少數(shù)幾個(gè)格式能夠流行開來(lái)。下面三種就是目前實(shí)力比較強(qiáng)的新興格式了:

          APNG 是 Mozilla 在 2008 年發(fā)布的一種圖片格式,旨在替換掉畫質(zhì)低劣的 GIF 動(dòng)畫。它實(shí)際上只是相當(dāng)于 PNG 格式的一個(gè)擴(kuò)展,所以 Mozilla 一直想把它合并到 PNG 標(biāo)準(zhǔn)里面去。然而 PNG 開發(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)漸漸流行開來(lái)。Mozilla 自己的 Firefox 首先支持了 APNG,隨后蘋果的 Safari 也開始有了支持, Chrome 目前也已經(jīng)嘗試開始支持 ,可以說(shuō)未來(lái)前景很好。

          WebP 是 Google 在 2010 年發(fā)布的圖片格式,希望以更高的壓縮比替代 JPEG。它用 VP8 視頻幀內(nèi)編碼作為其算法基礎(chǔ),取得了不錯(cuò)的壓縮效果。它支持有損和無(wú)損壓縮、支持完整的透明通道、也支持多幀動(dòng)畫,并且沒(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)畫。(騰訊技術(shù)團(tuán)隊(duì)在《騰訊技術(shù)分享:社交網(wǎng)絡(luò)圖片的帶寬壓縮技術(shù)演進(jìn)之路》、《騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(圖片壓縮篇)》這兩篇文章中都有提到WebP格式的技術(shù)實(shí)踐)

          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)畫。 Fabrice Bellard 聰明的地方在于,他知道自己一個(gè)人無(wú)法得到各大瀏覽器廠商的支持,所以他還特地開發(fā)了 Javascript 版的解碼器,任何瀏覽器只要加載了這個(gè) 76KB 大小的 JS 文件,就可以直接顯示 BPG 格式的圖片了。目前阻礙它流行的原因就是 HEVC 的版權(quán)問(wèn)題和它較長(zhǎng)的編碼解碼時(shí)間。盡管這個(gè)圖片格式才剛剛發(fā)布一年,但已經(jīng)有不少?gòu)S子開始試用了,比如阿里騰訊

          5、移動(dòng)端圖片類型的支持情況

          目前主流的移動(dòng)端對(duì)圖片格式的支持情況如何呢?

          我們分別來(lái)看一下 Android 和 iOS 目前的圖片編解碼架構(gòu)吧:

          Android 的圖片編碼解碼是由 Skia 圖形庫(kù)負(fù)責(zé)的,Skia 通過(guò)掛接第三方開源庫(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 格式的支持。在上層,開發(fā)者可以直接調(diào)用 ImageIO 對(duì)上面這些圖片格式進(jìn)行編碼和解碼。對(duì)于動(dòng)圖來(lái)說(shuō),開發(fā)者可以解碼動(dòng)畫 GIF 和 APNG、可以編碼動(dòng)畫 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 專門針對(duì) JPEG 的編解碼開發(fā)了 AppleJPEG.framework,實(shí)現(xiàn)了性能更高的硬編碼和硬解碼,只有當(dāng)硬編碼解碼失敗時(shí),libjpeg 才會(huì)被用到。

          6、靜態(tài)圖片的編碼與解碼

          由于我目前主要是做 iOS 開發(fā),所以下面的性能評(píng)測(cè)都是基于 iPhone 的,主要測(cè)試代碼可以在這里看到。

          測(cè)試素材很少,只有兩個(gè):

          第一張是Dribbble 的 Logo,包含 Alpha 通道,用于測(cè)試簡(jiǎn)單的、圖形類的圖像。第二張經(jīng)典的 Lena 圖,用于測(cè)試照片類的、具有豐富細(xì)節(jié)的圖像。每個(gè)圖像都有 64×64、128×128、256×256、512×512 四種分辨率。測(cè)試素材過(guò)少可能導(dǎo)致某些測(cè)試不夠準(zhǔn)確,但作為參考大致是沒(méi)問(wèn)題的。

          6.1 JPEG

          目前比較知名的 JPEG 庫(kù)有以下三個(gè):

          1)libjpeg:開發(fā)時(shí)間最早,使用最廣泛的 JPEG 庫(kù)。由于 JPEG 標(biāo)準(zhǔn)過(guò)于復(fù)雜和模糊,并沒(méi)有其他人去實(shí)現(xiàn),所以這個(gè)庫(kù)是 JPEG 的事實(shí)標(biāo)準(zhǔn);

          2)libjpeg-turbo:一個(gè)致力于提升編解碼速度的 JPEG 庫(kù)。它基于 libjpeg 進(jìn)行了改造,用 SIMD 指令集 (MMX、SSE2、NEON) 重寫了部分代碼,官網(wǎng)稱相對(duì)于 libjpeg 有 2 到 4 倍的性能提升;

          3)MozJPEG: 一個(gè)致力于提升壓縮比的 JPEG 庫(kù)。它是 Mozilla 在 2014 年發(fā)布的基于 libjpeg-turbo 進(jìn)行改造的庫(kù),相對(duì)于 libjpeg 有 5% ~ 15%  的壓縮比提升,但相應(yīng)的其編碼速度也慢了很多。

          除了上面這三個(gè)庫(kù),蘋果自己也開發(fā)了一個(gè) AppleJPEG,但并沒(méi)有開源。其調(diào)用了芯片提供的 DSP 硬編碼和硬解碼的功能。雖然它不如上面這三個(gè)庫(kù)功能完善,但其性能非常高。在我的測(cè)試中,其編解碼速度通常是 libjpeg-turbo 的 1~2 倍。可惜的是,目前開發(fā)者并不能直接訪問(wèn)這個(gè)庫(kù)。

          下面是 ImageIO (AppleJPEG/libpng) 在 iPhone 6 上的編解碼性能:

          可以看到,JPEG 編碼中 quality 越小,圖片體積就越小,質(zhì)量越也差,編碼時(shí)間也越短。解碼時(shí)間并沒(méi)有很大的差距,可能是其大部分時(shí)間消耗在了函數(shù)調(diào)用、硬件調(diào)用上。蘋果在自己的相冊(cè) Demo 中提供的 quality 的默認(rèn)值是 0.9,在這個(gè)值附近,圖像質(zhì)量和體積、編碼解碼時(shí)間之間都能取得不錯(cuò)的平衡。

          6.2 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 編解碼。

          下面是 PNG 在 iPhone 6 上的編解碼性能:

          可以看到,在編解碼圖形類型(顏色少、細(xì)節(jié)少)的圖片時(shí),PNG 和 JPEG 差距并不大;但是對(duì)于照片類型(顏色和細(xì)節(jié)豐富)的圖片來(lái)說(shuō),PNG 在文件體積、編解碼速度上都差 JPEG 不少了。

          和 JPEG 不同,PNG 是無(wú)損壓縮,其并不能提供壓縮比的選項(xiàng),其壓縮比是有上限的。目前網(wǎng)上有很多針對(duì) PNG 進(jìn)行優(yōu)化的工具和服務(wù),旨在提升 PNG 的壓縮比。

          下面是常見(jiàn)的幾個(gè) PNG 壓縮工具的性能對(duì)比:

          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ì)師看一下顏色效果是否可以接受。

          6.3 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 的有損圖片起作用。開啟后內(nèi)部會(huì)用多線程解碼,CPU 占用會(huì)更高,解碼時(shí)間平均能縮短 10%~20%;

          bypass_filtering: 是否禁用濾波。該參數(shù)只對(duì)有損圖片起作用,開啟后大約能縮短 5%~10% 的解碼時(shí)間,但會(huì)造成一些顏色過(guò)渡平滑的區(qū)域產(chǎn)生色帶(banding);

          no_fancy_upsampling: 是否禁用上采樣。該參數(shù)只對(duì)有損圖片起作用。在我的測(cè)試中,開啟該參數(shù)后,解碼時(shí)間反而會(huì)增加 5~25%,同時(shí)會(huì)造成一些圖像細(xì)節(jié)的丟失,線條邊緣會(huì)增加雜色,顯得不自然。

          通常情況下,這三個(gè)參數(shù)都設(shè)為 NO 即可,如果要追求更高的解碼速度,則可以嘗試開啟 use_threads 和 bypass_filtering 這兩個(gè)參數(shù)。而 no_fancy_upsampling 在任何情況下都沒(méi)必要開啟。

          由于 WebP 測(cè)試數(shù)據(jù)較多,這里只貼一下 512x512 大小的一部分測(cè)試結(jié)果,感興趣的可以看看Excel附件(附件下載):

          對(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)相差不大了,而文件壓縮比卻能提升不少。

          6.4 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。

          libbpg 目前并沒(méi)有針對(duì) ARM NEON 做優(yōu)化,所以其在移動(dòng)端的性能表現(xiàn)一般。下面是 iPhone 6 上的性能測(cè)試:

          由于 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)化。

          7、動(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)上流行開來(lái),直到今天仍然難以被其他格式取代。盡管它非常古老,但其所用的原理和今天幾種新興格式幾乎一樣。

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

          這張表情由 6 幅靜態(tài)圖構(gòu)成,每幅圖片有一定的存活時(shí)間,連貫播放就形成了動(dòng)畫:

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

          在解碼動(dòng)圖時(shí),解碼器通常采用所謂“畫布模式”進(jìn)行渲染。想象一下:播放的區(qū)域是一張畫布,第一幀播放前先把畫布清空,然后完整的繪制上第一幀圖;播放第二幀時(shí),不再清空畫布,而是只把和第一幀不同的區(qū)域覆蓋到畫布上,就像油畫的創(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)前幀增量繪制到畫布上,不清空畫布;

          Restore to Background:繪制當(dāng)前幀之前,先把畫布清空為默認(rèn)背景色;

          Restore to Previous:繪制下一幀前,把先把畫布恢復(fù)為當(dāng)前幀的前一幀。

          Blend Mode (混合模式) :

          Blend None: 繪制時(shí),全部通道(包含Alpha通道)都會(huì)覆蓋到畫布,相當(dāng)于繪制前先清空畫布的指定區(qū)域;

          Blend over:繪制時(shí),Alpha 通道會(huì)被合成到畫布,即通常情況下兩張圖片重疊的效果。

          上面這些技術(shù),就是常見(jiàn)動(dòng)圖格式的基礎(chǔ)了,下面分別介紹一下不同動(dòng)圖格式的特點(diǎn)。

          7.1 GIF

          GIF 缺陷非常明顯:

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

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

          上面這是騰訊博客里的一張演示圖,可以看到 GIF 由于 Alpha 通道的問(wèn)題,產(chǎn)生了嚴(yán)重的“毛邊”現(xiàn)象。

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

          可以仔細(xì)觀察一下 QQ、微信等 App 里面的動(dòng)畫表情,幾乎每個(gè)表情都被一圈白邊所環(huán)繞,不得不說(shuō)是一種很無(wú)奈的解決方案。

          GIF 的制作工具有很多,但效果好、壓縮比高的工具非常少。對(duì)于已經(jīng)制作好的 GIF 來(lái)說(shuō),用 imagemagick 處理一下可以把文件體積壓縮不少。如果需要將視頻轉(zhuǎn)為 GIF,Cinemagraph Pro 是個(gè)不錯(cuò)的傻瓜化工具。文章《使用 FFmpeg 處理高質(zhì)量 GIF 圖片》介紹了如何用 ffmpeg 壓縮 GIF,雖然參數(shù)調(diào)節(jié)有點(diǎn)麻煩,但效果非常理想。

          下面是沒(méi)有經(jīng)過(guò)優(yōu)化的 GIF 和經(jīng)過(guò) ffmpeg 優(yōu)化編碼的 GIF,可以看到差距非常大:

          7.2 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)畫。APNG 壓縮最好的工具目前是 apngasm,大部分圖形化工具比如騰訊的 iSparta 都是基于這個(gè)工具開發(fā)的。

          就目前而言, APNG 是 GIF 最好的替代了:實(shí)現(xiàn)簡(jiǎn)單,可用范圍廣,壓縮比不錯(cuò),顯示效果好。

          7.3 WebP

          WebP 在 2010 年 發(fā)布時(shí)并沒(méi)有支持動(dòng)圖。2012 年 libwebp v0.2 的時(shí)候,Google 才開始嘗試支持動(dòng)畫,但其實(shí)現(xiàn)有很多問(wèn)題,性能也非常差,以至于 Chrome 團(tuán)隊(duì)一直都沒(méi)有接受。直到 2013 年,libwebp v0.4 時(shí),動(dòng)畫格式才穩(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 解碼。為了方便編譯,我寫了個(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)有其他什么更好的工具可以用了 (update: 在最近的 libwebp v0.6.0 中, Google 新提供了一個(gè) img2webp 命令專門用于制作動(dòng)圖的,效果不錯(cuò))。

          7.4 BPG

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

          我在這里寫了個(gè)簡(jiǎn)單的利用 libbpg 解碼動(dòng)圖的方法,如有需要可以參考下。

          8、動(dòng)圖性能對(duì)比

          我把下面這張 GIF 分別轉(zhuǎn)為 WebP、APNG、BPG 動(dòng)圖,并在 iPhone 6 上對(duì)其所有幀進(jìn)行解碼。

          評(píng)測(cè)結(jié)果如下:

          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)的開發(fā)者,可以試試我開發(fā)的 YYWebImage,它支持 APNG、WebP、GIF 動(dòng)圖的異步加載與播放、編碼與解碼,支持漸進(jìn)式圖像加載,可以替代 SDWebImage、PINRemoteImage、FLAnimatedImage 等開源庫(kù)。

          附錄:更多移動(dòng)端即時(shí)通訊應(yīng)用開發(fā)文章

          移動(dòng)端IM開發(fā)者必讀(一):通俗易懂,理解移動(dòng)網(wǎng)絡(luò)的“弱”和“慢”

          移動(dòng)端IM開發(fā)者必讀(二):史上最全移動(dòng)弱網(wǎng)絡(luò)優(yōu)化方法總結(jié)

          從客戶端的角度來(lái)談?wù)勔苿?dòng)端IM的消息可靠性和送達(dá)機(jī)制

          現(xiàn)代移動(dòng)端網(wǎng)絡(luò)短連接的優(yōu)化手段總結(jié):請(qǐng)求速度、弱網(wǎng)適應(yīng)、安全保障

          騰訊技術(shù)分享:社交網(wǎng)絡(luò)圖片的帶寬壓縮技術(shù)演進(jìn)之路

          小白必讀:閑話HTTP短連接中的Session和Token

          IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課:正確理解前置HTTP SSO單點(diǎn)登陸接口的原理

          移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?

          移動(dòng)端IM開發(fā)需要面對(duì)的技術(shù)問(wèn)題

          開發(fā)IM是自己設(shè)計(jì)協(xié)議用字節(jié)流好還是字符流好?

          請(qǐng)問(wèn)有人知道語(yǔ)音留言聊天的主流實(shí)現(xiàn)方式嗎?

          IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞

          IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞

          如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?

          一個(gè)低成本確保IM消息時(shí)序的方法探討

          IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?

          IM群聊消息如此復(fù)雜,如何保證不丟不重?

          談?wù)勔苿?dòng)端 IM 開發(fā)中登錄請(qǐng)求的優(yōu)化

          移動(dòng)端IM登錄時(shí)拉取數(shù)據(jù)如何作到省流量?

          淺談移動(dòng)端IM的多點(diǎn)登陸和消息漫游原理

          完全自已開發(fā)的IM該如何設(shè)計(jì)“失敗重試”機(jī)制?

          通俗易懂:基于集群的移動(dòng)端IM接入層負(fù)載均衡方案分享

          微信對(duì)網(wǎng)絡(luò)影響的技術(shù)試驗(yàn)及分析(論文全文)

          即時(shí)通訊系統(tǒng)的原理、技術(shù)和應(yīng)用(技術(shù)論文)

          開源IM工程“蘑菇街TeamTalk”的現(xiàn)狀:一場(chǎng)有始無(wú)終的開源秀

          QQ音樂(lè)團(tuán)隊(duì)分享:Android中的圖片壓縮技術(shù)詳解(上篇)

          QQ音樂(lè)團(tuán)隊(duì)分享:Android中的圖片壓縮技術(shù)詳解(下篇)

          騰訊原創(chuàng)分享(一):如何大幅提升移動(dòng)網(wǎng)絡(luò)下手機(jī)QQ的圖片傳輸速度和成功率

          騰訊原創(chuàng)分享(二):如何大幅壓縮移動(dòng)網(wǎng)絡(luò)下APP的流量消耗(上篇)

          騰訊原創(chuàng)分享(三):如何大幅壓縮移動(dòng)網(wǎng)絡(luò)下APP的流量消耗(下篇)

          如約而至:微信自用的移動(dòng)端IM網(wǎng)絡(luò)層跨平臺(tái)組件庫(kù)Mars已正式開源

          基于社交網(wǎng)絡(luò)的Yelp是如何實(shí)現(xiàn)海量用戶圖片的無(wú)損壓縮的?

          騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(圖片壓縮篇)

          騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(音視頻技術(shù)篇)

          為什么說(shuō)即時(shí)通訊社交APP創(chuàng)業(yè)就是一個(gè)坑?

          字符編碼那點(diǎn)事:快速理解ASCII、Unicode、GBK和UTF-8

          深入學(xué)習(xí)移動(dòng)端主流圖片格式的特點(diǎn)、性能、調(diào)優(yōu)等

          >> 更多同類文章 ……

          (本文同步發(fā)布于:http://www.52im.net/thread-1802-1-1.html



          作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時(shí)通訊開發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 廉江市| 威海市| 阳春市| 关岭| 扎囊县| 汉寿县| 镇平县| 兴隆县| 潮州市| 华池县| 永丰县| 盐源县| 巍山| 安化县| 炉霍县| 比如县| 三河市| 上虞市| 武平县| 木兰县| 法库县| 哈尔滨市| 鹰潭市| 海伦市| 容城县| 拉孜县| 许昌县| 临泉县| 藁城市| 云梦县| 徐州市| 定日县| 柳河县| 萨嘎县| 洪泽县| 阳山县| 德钦县| 清水河县| 宜宾市| 高雄县| 海林市|