大Bitmap的載入

2021-07-02 00:04:24 字數 4330 閱讀 1822

高效使用bitmaps有什麼好處?

我們常常提到的「android程式優化」,通常指的是效能和記憶體的優化,即:更快的響應速度,更低的記憶體占用。android程式的效能和記憶體問題,大部分都和緊密相關,而的載入在很多情況下很用到bitmap(位圖)這個類。而由於bitmap自身的特性(將每個畫素的屬性全部儲存在記憶體中),導致稍有不慎就會建立出乙個占用記憶體非常大的bitmap物件,從而導致載入過慢,還會有記憶體溢位的風險。所以,android程式要做優化,bitmap的優化是必不可少的一步。

需要對bitmap進行優化

的情形

首先請看一行**: ?

1mimageview.setimageresource(r.drawable.my_image);

這是一行從資源檔案中載入到imageview的**。通常這段**沒什麼問題,但有些情況下,你需要對這段**進行優化。例如當的尺寸遠遠大於imageview的尺寸時,或者當你要在乙個listview或gridview中批量載入一些大小未知的時。實際上,以上這行**會在執行時使用bitmapfactory.decodestream()方法將資源生成乙個bitmap,然後由這個bitmap生成乙個drawable,最後再將這個drawable設定到imageview。由於在過程中生成了bitmap,因此如果你使用的過大,就會導致效能和記憶體占用的問題。另外,需要優化的情形不止這一種,這裡就不再列舉。

下面分步說明使用**來減小bitmap的尺寸從而達到減小記憶體占用的方法:

1. 獲取原尺寸

通常,我們使用bitmapfactory.decoderesource()方法來從資源檔案中讀取一

張並生成乙個bitmap。但如果使用乙個bitmapfactory.options物件,並把該物件的injustdecodebounds屬性設定為true,decoderesource()方法就不會生成bitmap物件,而僅僅是讀取該的尺寸和型別資訊:

? 1

2

3

4

5

6

bitmapfactory.options options =newbitmapfactory.options();

options.injustdecodebounds =true;

bitmapfactory.decoderesource(getresources(), r.id.myimage, options);

intimageheight = options.outheight;

intimagewidth = options.outwidth;

string imagetype = options.outmimetype;

2. 根據原圖尺寸和目標區域的尺寸計算出合適的bitmap尺寸

bitmapfactory.options類有乙個引數insamplesize,該引數為int型,他的值指示了在解析為bitmap時在長寬兩個方向上畫素縮小的倍數。insamplesize的預設值和最小值為1(當小於1時,解碼器將該值當做1來處理),且在大於1時,該值只能為2的冪(當不為2的冪時,解碼器會取與該值最接近的2的冪)。例如,當insamplesize為2時,乙個2000*1000的,將被縮小為1000*500,相應地,它的畫素數和記憶體占用都被縮小為了原來的1/4: ?

12

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

publicstaticintcalculateinsamplesize(

bitmapfactory.options options,intreqwidth,intreqheight)

}

returninsamplesize;

}

3. 根據計算出的insamplesize生成bitmap ?

12

3

4

5

6

7

8

9

10

11

12

13

14

15

publicstaticbitmap decodesampledbitmapfromresource(resources res,intresid,

intreqwidth,intreqheight)

這裡有一點要注意,就是要在第二遍decode之前把injustdecodebounds設定回false。

4. 呼叫以上的

decodesampledbitmapfromresource方法,使用自定尺寸的bitmap。

如果你要將一張大圖設定為乙個100*100的縮圖,執行以下**: ?

1mimageview.setimagebitmap(decodesampledbitmapfromresource(getresources(), r.id.myimage,100,100));

到此,使用decoderesource()方法將乙個大**析為小尺寸bitmap的應用就完成了。同理,還可以使用decodestream(),decodefile()等方法做相同的事,原理是一樣的。

延伸:乙個bitmap到底占用多大記憶體?系統給每個應用程式分配多大記憶體?

· bitmap占用的記憶體為:畫素總數 * 每個畫素占用的記憶體。在android中,bitmap有四種畫素型別:argb_8888、argb_4444、argb_565、alpha_8,他們每個畫素占用的位元組數分別為4、2、2、1。因此,乙個2000*1000的argb_8888型別的bitmap占用的記憶體為2000*1000*4=8000000b=8mb。

· android根據裝置螢幕尺寸和dpi的不同,給系統分配的單應用程式記憶體大小也不同,具體如下表(**取自android 4.4 compatibility definition document (cdd)):

螢幕尺寸

dpi應用記憶體

small / normal / large

ldpi / mdpi

16mb

small / normal / large

tvdpi / hdpi

32mb

small / normal / large

xhdpi

64mb

small / normal / large

400dpi

96mb

small / normal / large

xxhdpi

128mb

xlarge

mdpi

32mb

xlarge

tvdpi / hdpi

64mb

xlarge

xhdpi

128mb

xlarge

400dpi

192mb

xlarge

xxhdpi

256mb

Bitmap的高效載入

如何高效的載入乙個bitmap,這是乙個很有意義的話題,因為在我們開發的過程中,經常會遇到這樣錯誤 outofmemoryerror 這樣的錯誤,很多時候都是因為載入bitmap出現的記憶體溢位.如何載入乙個bitmap bitmap在andriod中指的是一張,那麼如何載入乙個?bitmapfac...

Bitmap的載入和Cache

載入bitmap bitmapfactory decodefile decoderesource decodestream decodebytearray 高效載入bitmap的核心思想 採用bitmapfactory.options,使用insamplesize 取樣率 引數來縮放 若為1則取樣後...

Bitmap的載入與快取

android系統中一般用bitmap物件表示,它支援png,jpg等常見格式。通常情況下的體積都比較大,單個應用允許使用的記憶體又是有限的,所以我們需要採取一些手段減少記憶體占用並提高載入速度。假設我們用imageview顯示,通常它的尺寸要比的尺寸小很多,那麼把整個載入進記憶體顯然是沒有必要的。...