重拾Android之路之圖片格式調(diào)研(轉(zhuǎn))

引言

在上篇重拾Android之路之圖片(高效加載大圖、多圖解決方案呐萨,有效避免程序OOM)中,我提到了移動端加載圖片網(wǎng)絡(luò)資源該選擇什么樣的格式。

本節(jié)轉(zhuǎn)自https://blog.ibireme.com/2015/11/02/mobile_image_benchmark/

摘取些節(jié)點來跟大家分享谴分。

摘錄

圖片通常是移動端流量耗費最多的部分,并且占據(jù)著重要的視覺空間镀脂。合理的圖片格式選用和優(yōu)化可以為你節(jié)省帶寬牺蹄、提升視覺效果。在這里我會分析一下目前主流和新興的幾種圖片格式的特點薄翅、性能分析沙兰、參數(shù)調(diào)優(yōu)氓奈,以及相關(guān)開源庫的選擇。

幾種圖片格式的簡介

首先談一下大家耳熟能詳?shù)膸追N老牌的圖片格式吧:

JPEG 是目前最常見的圖片格式鼎天,它誕生于 1992 年舀奶,是一個很古老的格式。它只支持有損壓縮训措,其壓縮算法可以精確控制壓縮比伪节,以圖像質(zhì)量換得存儲空間。由于它太過常見绩鸣,以至于許多移動設(shè)備的 CPU 都支持針對它的硬編碼與硬解碼怀大。

PNG 誕生在 1995 年,比 JPEG 晚幾年呀闻。它本身的設(shè)計目的是替代 GIF格式化借,所以它與 GIF 有更多相似的地方。PNG 只支持無損壓縮捡多,所以它的壓縮比是有上限的蓖康。相對于 JPEG 和 GIF 來說,它最大的優(yōu)勢在于支持完整的透明通道垒手。

GIF 誕生于 1987 年蒜焊,隨著初代互聯(lián)網(wǎng)流行開來。它有很多缺點科贬,比如通常情況下只支持 256 種顏色泳梆、透明通道只有 1 bit、文件壓縮比不高榜掌。它唯一的優(yōu)勢就是支持多幀動畫优妙,憑借這個特性,它得以從 Windows 1.0 時代流行至今憎账,而且仍然大受歡迎套硼。

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

APNG 是 Mozilla 在 2008 年發(fā)布的一種圖片格式做入,旨在替換掉畫質(zhì)低劣的 GIF 動畫。它實際上只是相當(dāng)于 PNG 格式的一個擴展同衣,所以 Mozilla 一直想把它合并到 PNG 標(biāo)準里面去竟块。然而 PNG 開發(fā)組并沒有接受 APNG 這個擴展,而是一直在推進它自己的 MNG 動圖格式耐齐。MNG 格式過于復(fù)雜以至于并沒有什么系統(tǒng)或瀏覽器支持浪秘,而 APNG 格式由于簡單容易實現(xiàn),目前已經(jīng)漸漸流行開來埠况。Mozilla 自己的 Firefox 首先支持了 APNG耸携,隨后蘋果的 Safari 也開始有了支持, Chrome 目前也已經(jīng)嘗試開始支持 辕翰,可以說未來前景很好夺衍。

WebP 是 Google 在 2010 年發(fā)布的圖片格式,希望以更高的壓縮比替代 JPEG喜命。它用 VP8 視頻幀內(nèi)編碼作為其算法基礎(chǔ)沟沙,取得了不錯的壓縮效果。它支持有損和無損壓縮壁榕、支持完整的透明通道矛紫、也支持多幀動畫,并且沒有版權(quán)問題牌里,是一種非常理想的圖片格式颊咬。借由 Google 在網(wǎng)絡(luò)世界的影響力,WebP 在幾年的時間內(nèi)已經(jīng)得到了廣泛的應(yīng)用二庵√叭荆看看你手機里的 App:微博、微信催享、QQ杭隙、淘寶、網(wǎng)易新聞等等因妙,每個 App 里都有 WebP 的身影痰憎。Facebook 則更進一步,用 WebP 來顯示聊天界面的貼紙動畫攀涵。

BPG 是著名程序員 Fabrice Bellard 在去年 (2014年) 發(fā)布的一款超高壓縮比的圖片格式铣耘。這個程序員有些人可能感覺面生,但說起他的作品 FFmpeg以故、QEMU 大家想必是都知道的蜗细。BPG 使用 HEVC (即 H.265) 幀內(nèi)編碼作為其算法基礎(chǔ),就這點而言,它毋庸置疑是當(dāng)下最為先進的圖片壓縮格式炉媒。相對于 JP2踪区、JPEG-XR、WebP 來說吊骤,同等體積下 BPG 能提供更高的圖像質(zhì)量缎岗。另外,得益于它本身基于視頻編碼算法的特性白粉,它能以非常小的文件體積保存多幀動畫传泊。 Fabrice Bellard 聰明的地方在于,他知道自己一個人無法得到各大瀏覽器廠商的支持鸭巴,所以他還特地開發(fā)了 Javascript 版的解碼器眷细,任何瀏覽器只要加載了這個 76KB 大小的 JS 文件,就可以直接顯示 BPG 格式的圖片了奕扣。目前阻礙它流行的原因就是 HEVC 的版權(quán)問題和它較長的編碼解碼時間薪鹦。盡管這個圖片格式才剛剛發(fā)布一年,但已經(jīng)有不少廠子開始試用了惯豆,比如阿里騰訊池磁。

移動端圖片類型的支持情況

目前主流的移動端對圖片格式的支持情況如何呢?我們分別來看一下 Android 和 iOS 目前的圖片編解碼架構(gòu)吧:

Android 的圖片編碼解碼是由 Skia 圖形庫負責(zé)的楷兽,Skia 通過掛接第三方開源庫實現(xiàn)了常見的圖片格式的編解碼支持地熄。目前來說,Android 原生支持的格式只有 JPEG芯杀、PNG端考、GIFBMPWebP (Android 4.0 加入)揭厚,在上層能直接調(diào)用的編碼方式也只有 JPEG却特、PNG、WebP 這三種筛圆。目前來說 Android 還不支持直接的動圖編解碼裂明。

iOS 底層是用 ImageIO.framework 實現(xiàn)的圖片編解碼。目前 iOS 原生支持的格式有:JPEG太援、JPEG2000闽晦、PNG、GIF提岔、BMP仙蛉、ICO、TIFF碱蒙、PICT荠瘪,自 iOS 8.0 起,ImageIO 又加入了 APNG、SVG哀墓、RAW 格式的支持鞭莽。在上層,開發(fā)者可以直接調(diào)用 ImageIO 對上面這些圖片格式進行編碼和解碼麸祷。對于動圖來說,開發(fā)者可以解碼動畫 GIF 和 APNG褒搔、可以編碼動畫 GIF阶牍。

兩個平臺在導(dǎo)入第三方編解碼庫時,都多少對他們進行了一些修改星瘾,比如 Android 對 libjpeg 等進行調(diào)整以更好的控制內(nèi)存走孽,iOS 對 libpng 進行了修改以支持 APNG,并增加了多線程編解碼的特性琳状。除此之外磕瓷,iOS 專門針對 JPEG 的編解碼開發(fā)了 AppleJPEG.framework,實現(xiàn)了性能更高的硬編碼和硬解碼念逞,只有當(dāng)硬編碼解碼失敗時困食,libjpeg 才會被用到。


選型

在移動端翎承,圖片一直是流量大頭硕盹,一個簡單的運營網(wǎng)頁,圖片大小動不動就以MB為單位叨咖,為了加快網(wǎng)頁呈現(xiàn)的速度瘩例,我們必須使用最適合圖片質(zhì)量,這里所說的合適指圖片的清晰度和大小達到合格的要求甸各。

前端常常會碰到這種情況垛贤,一個網(wǎng)頁都是圖片,需要你壓縮圖片到適合的分辨率趣倾,分辨率低了容易失真用戶體驗不好聘惦,高了圖片質(zhì)量太大導(dǎo)致加載慢,所以經(jīng)常會找一個合適的臨界點來選擇圖片的分辨率誊酌。

我們選擇了某個分辨率來作為合適臨界點部凑,卻發(fā)現(xiàn)圖片依然很大,希望它可以再小些碧浊,給用戶更快的呈現(xiàn)速度涂邀。對于 JPEG、PNG 和 GIF 這些圖片格式的優(yōu)化幾乎已經(jīng)達到了極致箱锐, 若想改變現(xiàn)狀開辟新局面比勉,便要有釜底抽薪的膽量和氣魄,而 Google 給了我們一個新選擇:WebP。

什么是webP?

WebP(發(fā)音 weppy)浩聋,是一種支持有損壓縮無損壓縮圖片文件格式观蜗,派生自圖像編碼格式 VP8。根據(jù) Google 的測試衣洁,無損壓縮后的 WebP 比 PNG 文件少了 45% 的文件大小墓捻,即使這些 PNG 文件經(jīng)過其他壓縮工具壓縮之后,WebP 還是可以減少 28% 的文件大小坊夫。相比JPEG文件“在質(zhì)量相同的情況下砖第,WebP格式圖像的體積要比JPEG格式圖像小40%。2010 年發(fā)布的 WebP 已經(jīng)不算是新鮮事物了环凿,在Google 的明星產(chǎn)品如 Youtube梧兼、Gmail、Google Play 中都可以看到 WebP 的身影智听,而 Chrome 網(wǎng)上商店甚至已完全使用了 WebP羽杰。國外公司如 Facebook、ebay 和國內(nèi)公司如騰訊到推、淘寶考赛、美團等也早已嘗鮮。目前 WebP 也在我廠很多的項目中得到應(yīng)用环肘,如騰訊新聞客戶端欲虚、騰訊網(wǎng)、QQ空間等悔雹,同時也有一些針對 WebP 的圖片格式轉(zhuǎn)換工具复哆,如智圖,iSparta(http://isparta.github.io/)等腌零。

知道了webP圖片格式梯找,我們再來看以下兩組數(shù)據(jù):

webP支持情況:
安卓手機系統(tǒng)分布:

從上面的兩組數(shù)據(jù)我們可以得到:

1: webP在安卓4.3以上瀏覽器中已經(jīng)完全支持,其中4.0以上部分大部分支持(這組數(shù)據(jù)為展示益涧,如有需要查詢它的兼容性可以定位這個網(wǎng)站:http://caniuse.com/#search=webp
2:安卓系統(tǒng)大于4.0占95.7%锈锤,大于等于4.3的占64.7%,從這可觀的數(shù)據(jù)來說我們?yōu)槭裁床贿x擇webP的格式來加載圖片闲询。

Google Android版本分布圖(2017年10月03日)

說到這里久免,可能有人開始要噴水了,為了圖片極致加載扭弧,你放棄了部分用戶阎姥,導(dǎo)致這部分用戶連你的圖片都無法顯示,這個方式根本不行鸽捻,我們需要的是在圖片完全兼容的條件下呼巴,再選擇最優(yōu)圖片格式泽腮。的確,我們不應(yīng)該為了最優(yōu)圖片格式衣赶,而放棄圖片兼容性诊赊,那么這個問題就需要我們給出一個解決方案。我們是不是可以通用用戶的系統(tǒng)版本來選擇使用哪種圖片府瞄?這個回答是肯定的碧磅,我們完全可以通過判斷用戶的系統(tǒng)版本來選擇加載哪種類型的圖片格式。

navigator.userAgent

JS的這個方法作為前端我們再熟悉不過了遵馆。Chrome瀏覽器在移動端調(diào)試環(huán)境下console中輸入:

    var userAgent = navigator.userAgent;
    alert(userAgent);

不同瀏覽器中续崖,彈窗內(nèi)容都不相同,其中內(nèi)容數(shù)據(jù)所代表什么意思团搞,這里不再做解釋,如有不懂的可以訪問這個地址多艇,有很好的解釋:http://www.jb51.net/article/48532.htm逻恐;

如何使用webP圖片

用戶的版本我能已經(jīng)獲得了,那么什么情況下使用webP圖片的格式峻黍,是不是也可以通過JS來判斷呢复隆。
這里隨便code舉個例子:

html:

<body>
     <img src="" alt="" data-url="11.jpg" data-original="11.webp"/>
     <img src="" alt="" data-url="21.jpg" data-original="21.webp"/>
</body>

js:

    var userAgent = navigator.userAgent;
    var Android = userAgent.indexOf("Android");
    var AppleWebKit=userAgent.indexOf('AppleWebKit');
    var androidVersion = parseFloat(userAgent.slice(Android+8));
    var $img=document.getElementsByTagName('img');
    window.onload= function () {
        if(Android >= 0 && AppleWebKit>=0&&androidVersion>=4){
            forImg('data-original');
        }else{
            forImg('data-url');
        }
    }
    function forImg(data){
        for(var i=0;i<$img.length;i++){
            $img[i].setAttribute('src',$img[i].getAttribute(data));
        }
    }

這段代碼用于測試。

結(jié)果自己通過控制臺去查看姆涩,可以選擇控制臺中的network來對比加載的時間挽拂。

圖片優(yōu)化的拓展

有關(guān)圖片的優(yōu)化,通常我們會用到LruCache(使用軟引用骨饿、強制回收的辦法)亏栈,會用到SoftReference(使用url做key,bitmap做value的方法)宏赘,會用到根據(jù)手機屏幕來縮放圖片绒北,會及時回收圖片所占用的內(nèi)存等方法。但說實在的察署,這些方法治標(biāo)不治本闷游,圖片該多大還多大,從軟件上我們基本上能做到處理圖片的極限贴汪,那么只剩下考慮從硬件來上優(yōu)化圖片脐往,這就講到了今天所要說的webp。

其中webp不僅僅能應(yīng)用在Android上扳埂,同樣IOS和web端也同樣可以使用业簿。

有關(guān)webp的簡介,騰訊同學(xué)有詳細介紹聂喇,濃縮的精華辖源!從零開始帶你認識最新的圖片格式WEBP蔚携,我不再多說。

一張279k的png圖片可以轉(zhuǎn)換成67.5k的webp圖片克饶,而且不失真

step_1
添加webp支持酝蜒,添加so包和lib包

step_2
添加WebpUtils文件,里面有通過so包來處理webp文件成為byte數(shù)組的方法

step_3
應(yīng)用

效果圖:


Android Service和webp講解源碼 

附安卓SDK文檔給出的官方壓縮圖片算法:

public static Bitmap getBitmapBySize(String path, int width, int height) {  
        BitmapFactory.Options option = new BitmapFactory.Options();  
        option.inJustDecodeBounds = true;  
        BitmapFactory.decodeFile(path, option);  
        option.inSampleSize = computeSampleSize(option, -1, width * height);  
  
        option.inJustDecodeBounds = false;  
        Bitmap bitmap = null;  
        try {  
            bitmap = BitmapFactory.decodeFile(path, option);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return bitmap;  
    }  
  
    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {  
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);  
        int roundedSize;  
        if (initialSize <= 8) {  
            roundedSize = 1;  
            while (roundedSize < initialSize) {  
                roundedSize <<= 1;  
            }  
        } else {  
            roundedSize = (initialSize + 7) / 8 * 8;  
        }  
        return roundedSize;  
    }  
  
    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {  
        double w = options.outWidth;  
        double h = options.outHeight;  
        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));  
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));  
        if (upperBound < lowerBound) {  
            // return the larger one when there is no overlapping zone.  
            return lowerBound;  
        }  
        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {  
            return 1;  
        } else if (minSideLength == -1) {  
            return lowerBound;  
        } else {  
            return upperBound;  
        }  
    }  

推薦資源

濃縮的精華矾湃!從零開始帶你認識最新的圖片格式WEBP

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亡脑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子邀跃,更是在濱河造成了極大的恐慌霉咨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拍屑,死亡現(xiàn)場離奇詭異途戒,居然都是意外死亡喜爷,警方通過查閱死者的電腦和手機筹淫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茧彤,“玉大人蒜茴,你說我怎么就攤上這事星爪。” “怎么了粉私?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵顽腾,是天一觀的道長。 經(jīng)常有香客問我诺核,道長抄肖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任窖杀,我火速辦了婚禮憎瘸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘陈瘦。我一直安慰自己幌甘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布痊项。 她就那樣靜靜地躺著锅风,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞍泉。 梳的紋絲不亂的頭發(fā)上皱埠,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音咖驮,去河邊找鬼边器。 笑死训枢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的忘巧。 我是一名探鬼主播恒界,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼砚嘴!你這毒婦竟也來了十酣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤际长,失蹤者是張志新(化名)和其女友劉穎耸采,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體工育,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡虾宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了如绸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片文留。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖竭沫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骑篙,我是刑警寧澤蜕提,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站靶端,受9級特大地震影響谎势,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杨名,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一脏榆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧台谍,春花似錦须喂、人聲如沸趁蕊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蓖柔。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間列牺,已是汗流浹背九默。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓丐重,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扮惦。 傳聞我的和親對象是個殘疾皇子臀蛛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 圖片通常是移動端流量耗費最多的部分,并且占據(jù)著重要的視覺空間崖蜜。合理的圖片格式選用和優(yōu)化可以為你節(jié)省帶寬浊仆、提升視覺效...
    傻傻小蘿卜閱讀 748評論 1 9
  • 要講圖片格式還先得從圖像的基本數(shù)據(jù)結(jié)構(gòu)說起。在計算機中, 圖像是由一個個像素點組成豫领,像素點就是顏色點抡柿,而顏色最簡單...
    404ErrorCrash閱讀 3,697評論 0 3
  • 一、主流的圖片格式 1等恐、JPEG 目前最常見的圖片格式洲劣,它誕生于 1992 年,是一個很古老的格式鼠锈。它只支持有損壓...
    Evans_Xiao閱讀 1,978評論 0 0
  • 參考PNG、EPS星著、bmp购笆、jpg等幾種圖片格式有什么區(qū)別GIF/PNG/JPG和WEBP/base64/apng...
    合肥黑閱讀 12,449評論 0 15
  • 參考鏈接:SVG 圖像入門教程 & 使用SVG symbols建立圖標(biāo)系統(tǒng)
    answer1129閱讀 80評論 0 0