當前位置:
首頁 > 最新 > Bitmap 載入耗時長、佔用內存高,如何優化?

Bitmap 載入耗時長、佔用內存高,如何優化?

前言

圖片是移動端開發中司空見慣的內容,開發者多數時候都會涉及圖片載入的功能。Bitmap是圖片在Android中的一種承載方式,它可以被載入到需要展示圖片的地方,比如ImageView或是View的background。隨著移動設備的更新換代,圖片的解析度越來越高,載入Bitmap的時候就不得不考慮OOM的問題了。

1

Bitmap Factory

Android中Bitmap的載入一般是通過BitmapFactory類來實現的。BitmapFactory類提供多種載入方式,常用的幾個載入方式:

文件

資源

位元組數組

數據流

2

Problem

通常,直接調用BitmapFactory的上述幾個方法,傳遞相對應的參數就可以載入Bitmap了。Bitmap對象在Android應用程序中佔用的內存是非常高的。

一張480x800的圖片,Bitmap佔用內存計算:

不作任何處理,直接調用BitmapFactory的decode方法來載入Bitmap會有幾個問題:

圖片解析度高,Bitmap載入耗時長;

圖片解析度高,Bitmap佔用內存很高,可能出現OOM;

圖片數量很多,Bitmap佔用內存很高,可能出現OOM。

3

Solution

不知道大家注意到沒有,上述幾個decode方法都有一個共同的參數——Options,它其實是BitmapFactory的一個內部類,主要提供Bitmap載入配置參數。我們今天要討論的優化點就是從Options配置參數出發,減少Bitmap載入過程中的內存消耗,降低Bitmap載入耗時,盡量降低OOM出現的風險。

Options參數源碼

提取Options關鍵配置參數,看看源碼如何描述的:

Options參數分析

結合兩個參數的含義,要降低Bitmap內存佔用,需要根據期望圖片尺寸和原圖尺寸來計算最佳圖片採樣率,使得圖片在不失真的情況下內存佔用盡量小,然後使用計算出的最佳圖片採樣率來decode圖片bitmap,達到降低Bitmap內存佔用及減少decode操作耗時的目的。

??

那麼,如何能夠快速又不消耗內存地得到原圖尺寸呢?答案就是利用inJustDecodeBounds參數!設置Options的inJustDecodeBounds參數為true,此時執行一次decode操作即可在不消耗內存的條件小拿到原圖尺寸。

4

解決方案

??

結合上述Options參數分析,我們可以寫出一個簡單的解決方案:

計算期望圖片尺寸

??

如何計算呢?

??

假設我們最終要decode的bitmap尺寸是長(maxWidth)和寬(maxHeight),然後根據原圖尺寸的長寬比來按比例縮放計算,得到縮放後的期望尺寸desiredWidth和desiredHeight。為什麼要這麼做呢?因為預設的maxWidth和maxHeight,它們的比例並不一定跟原圖比例相符,按比例縮放後的期望尺寸才能保證最終圖片不變形。

??

具體演算法如下:

計算最佳圖片採樣率

??

根據前面對inSampleSize參數的解析,它的最終取值為2的指數倍。結合期望尺寸和原圖尺寸的比值,我們可以計算出一個最接近該比值的採樣率數值,把它作為最佳採樣率。

Powers of 2 : 2^n

2^0 = 1

2^1 = 2

2^2 = 4

2^3 = 8

2^4 = 16

2^5 = 32

2^6 = 64

2^7 = 128

2^8 = 256

2^9 = 512

2^10 = 1024

具體演算法如下:

5

最終實現

??

上述的解決方案經過我們的分解之後,一步一步實現了,最終的代碼實現如下:

6

結語

隨著Android系統越來越高度成熟,各種開源項目也層出不窮,在圖片載入這塊上就已經有很多優秀的開源項目了,比如早期的Android-Universal-Image-Loader,FackBook開源的Fresco以及Google開發人員開源的Glide(現已被Google採用)。

今天分享的Bitmap載入性能優化方案,也可以運用到項目工程中,比如圖片上傳功能模塊,既可以減少選擇圖片後的等待耗時,又可以上傳壓縮後的圖片文件,達到性能和體驗雙收目的。

「魅族開放平台」每周推出一篇魅族工程師的分享,如果覺得文章不錯,就請分享給身邊的朋友們吧,歡迎留言討論~

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 魅族開放平台 的精彩文章:

TAG:魅族開放平台 |