使用BitmapFactory不同方法解析Bitmap的簡單分析,bitmapfactory

來源:互聯網
上載者:User

使用BitmapFactory不同方法解析Bitmap的簡單分析,bitmapfactory
使用BitmapFactory不同方法解析Bitmap的簡單分析

相信大家在平時進行Android的開發過程中,都有使用過Bitmap。

其實Google自己也有一個簡單介紹Bitmap如何使用的文章,Manage Bitmap Memory。在這裡對一些簡單的Bitmap記憶體最佳化做了介紹。

其實我寫這篇文章的初衷是由於最近在寫一個涉及到很多張Bitmap顯示的控制項,但是由於圖片過多,假如完全顯示會導致OOM,因此需要建立了一個圖片緩衝,

現在我手上有800多張136px*128px大小的圖片,我現在分別通過將圖片放在磁碟檔案,assets目錄,drawable的各個目錄下,來測試通過BitmapFactory建立圖片的效能。

測試平台為:Genymotion 類比機上的 Preview-GoogleNexus6-5.1.0-API22-1440x2560。

對圖片混存的最大限制為當前應用程式的 1/8 最大記憶體。

具體讀取Bitmap的代碼就不再放上來了,反正就是使用BitmapFactory的一些方法去讀取,也挺簡單的。

測試結果如下:

效能點 File Assets drawable drawable-ldpi drawable-mdpi
讀取時間總耗時 1360 406 2550 4100 2545
相同記憶體最大圖片數 181 181 15 9 15
產生圖片尺寸 136*128 136*128 476*448 635*597 476*448
drawalbe-hdpi drawable-xhdpi drawable-xxhdpi drawable-xxxhdpi
讀取時間總耗時 1479 1132 940 619
相同記憶體最大圖片數 34 60 134 237
產生圖片尺寸 317*299 238*224 159*149 119*112

從上表中可以看出,對於同一套圖片而言,從file,assets以及drawable下所取出的大小記憶體,以及消耗時間均不相同,總的來說從Assets目錄下擷取速度最快,消耗的記憶體相對較少。

而從drawable各目錄下取出的圖片隨著螢幕像素的遞減,其尺寸越大,佔用記憶體越大,讀取耗時越多。

我們仔細觀察BitmapFactory中各個方法,我們會發現,不論是decodeResource ,decodeFile,他們最後都會調用decodeStream這個方法來擷取Bitmap對象。

對於從檔案和assets對象中擷取bitmap而言,他們之間唯一的區別就是一個是從本地磁碟上讀取,一個是從assets中讀取,那麼對一個應用而言,讀取自身的速度會快一些,我們也可以理解。

而對於drawable目錄裡的圖片而言,為什麼他們讀取出來的圖片尺寸會不一樣呢?

我記得在Android開發人員官網上,Google曾經說過

If your application’s minSdkVersion is 4 or greater, you do not need default drawable resources when you provide alternative drawable resources with the screen density qualifier. Even without default drawable resources, Android can find the best match among the alternative screen densities and scale the bitmaps as necessary. However, for the best experience on all types of devices, you should provide alternative drawables for all three types of density.

這句話的大概意思就是對於最低sdk版本為4的應用而言,假如我們在某一個drawable路徑下已經提供了一個drawable資源,那我們就不需要在預設的drawable目錄下提供預設資源(要知道類似於values,layout這些xml檔案,必須要有一個預設的配置項,而drawable只要你有一個就夠了)。Android系統會自動找到最匹配的想,然後對找到的bitmap進行縮放,以供使用。

因此我們可以推斷出之所以放置在各個drawable目錄下導致產生的bitmap尺寸不同就是因為Android系統為我們進行了自動縮放。

接下來我們來看看Android是如何?bitmap資源自動縮放的。

先從Java層的代碼入手,我們發現在BitmapFactory中,decodeResource擷取Bitmap的代碼如下:

final TypedValue value = new TypedValue();is = res.openRawResource(id, value);bm = decodeResourceStream(res, value, is, null, opts);

在deoceResourceStream中代碼如下:

if (opts.inDensity == 0 && value != null) {    final int density = value.density;    if (density == TypedValue.DENSITY_DEFAULT) {        opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;    } else if (density != TypedValue.DENSITY_NONE) {        opts.inDensity = density;    }}if (opts.inTargetDensity == 0 && res != null) {    opts.inTargetDensity = res.getDisplayMetrics().densityDpi;}return decodeStream(is, pad, opts);

在這裡我們也可看出來,Android首先從TypeValue中擷取到了最匹配的drawable對象的螢幕像素密度,然後將drawable對象的螢幕像素同裝置自身的螢幕像素密度傳入opts對象中,再調取decodeStream方法,進行最後的bitmap解析。

因此Android通過BitmapFactory解析drawable中的圖片檔案時其實會按照圖片所處檔案夾的圖片像素密度同現有裝置的像素密度進行縮放。

根據bitmap的定義,長寬尺寸越大,其佔用記憶體也會成平方級數的增長,因此就會發現對於同一張圖片,放置圖片的drawable檔案夾的螢幕像素越低,其在同一裝置上佔用的記憶體就會越大。(Ps:真實使用的時候,放置在不同drawable檔案夾下的相同圖片的尺寸也必定不同,故這其實沒有什麼大問題。)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.