日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高效使用Bitmaps(一) 大Bitmap的加载

發(fā)布時(shí)間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高效使用Bitmaps(一) 大Bitmap的加载 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://my.oschina.net/rengwuxian/blog/182885

高效使用Bitmaps有什么好處?

我 們常常提到的“Android程序優(yōu)化”,通常指的是性能和內(nèi)存的優(yōu)化,即:更快的響應(yīng)速度,更低的內(nèi)存占用。Android程序的性能和內(nèi)存問題,大部 分都和圖片緊密相關(guān),而圖片的加載在很多情況下很用到Bitmap(位圖)這個(gè)類。而由于Bitmap自身的特性(將每個(gè)像素的屬性全部保存在內(nèi)存中), 導(dǎo)致稍有不慎就會(huì)創(chuàng)建出一個(gè)占用內(nèi)存非常大的Bitmap對(duì)象,從而導(dǎo)致加載過慢,還會(huì)有內(nèi)存溢出的風(fēng)險(xiǎn)。所以,Android程序要做優(yōu) 化,Bitmap的優(yōu)化是必不可少的一步。

需要對(duì)Bitmap進(jìn)行優(yōu)化的情形

首先請(qǐng)看一行代碼:

1mImageView.setImageResource(R.drawable.my_image);

這是一行從資源文件中加載圖片到ImageView的代碼。通常這段代碼沒什么問 題,但有些情況下,你需要對(duì)這段代碼進(jìn)行優(yōu)化。例如當(dāng)圖片的尺寸遠(yuǎn)遠(yuǎn)大于ImageView的尺寸時(shí),或者當(dāng)你要在一個(gè)ListView或 GridView中批量加載一些大小未知的圖片時(shí)。實(shí)際上,以上這行代碼會(huì)在運(yùn)行時(shí)使用BitmapFactory.decodeStream()方法將 資源圖片生成一個(gè)Bitmap,然后由這個(gè)Bitmap生成一個(gè)Drawable,最后再將這個(gè)Drawable設(shè)置到ImageView。由于在過程中 生成了Bitmap,因此如果你使用的圖片過大,就會(huì)導(dǎo)致性能和內(nèi)存占用的問題。另外,需要優(yōu)化的情形不止這一種,這里就不再列舉。

下面分步說明使用代碼來減小Bitmap的尺寸從而達(dá)到減小內(nèi)存占用的方法:

1. 獲取原圖片尺寸

通常,我們使用BitmapFactory.decodeResource()方法來從資源文件中讀取一張 圖片并生成一個(gè)Bitmap。但如果使用一個(gè)BitmapFactory.Options對(duì)象,并把該對(duì)象的inJustDecodeBounds屬性設(shè) 置為true,decodeResource()方法就不會(huì)生成Bitmap對(duì)象,而僅僅是讀取該圖片的尺寸和類型信息:

?

?

1BitmapFactory.Options options = new BitmapFactory.Options();
2options.inJustDecodeBounds = true;
3BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
4int imageHeight = options.outHeight;
5int imageWidth = options.outWidth;
6String imageType = options.outMimeType;

2. 根據(jù)原圖尺寸和目標(biāo)區(qū)域的尺寸計(jì)算出合適的Bitmap尺寸

BitmapFactory.Options類有一個(gè)參數(shù) inSampleSize,該參數(shù)為int型,他的值指示了在解析圖片為Bitmap時(shí)在長(zhǎng)寬兩個(gè)方向上像素縮小的倍數(shù)。inSampleSize的默認(rèn) 值和最小值為1(當(dāng)小于1時(shí),解碼器將該值當(dāng)做1來處理),且在大于1時(shí),該值只能為2的冪(當(dāng)不為2的冪時(shí),解碼器會(huì)取與該值最接近的2的冪)。例如, 當(dāng)inSampleSize為2時(shí),一個(gè)2000*1000的圖片,將被縮小為1000*500,相應(yīng)地,它的像素?cái)?shù)和內(nèi)存占用都被縮小為了原來的 1/4:

01public static int calculateInSampleSize(
02????????????BitmapFactory.Options options, int reqWidth, int reqHeight) {
03????// 原始圖片的寬高
04????final int height = options.outHeight;
05????final int width = options.outWidth;
06????int inSampleSize = 1;
07?
08????if (height > reqHeight || width > reqWidth) {
09?
10????????final int halfHeight = height / 2;
11????????final int halfWidth = width / 2;
12?
13????????// 在保證解析出的bitmap寬高分別大于目標(biāo)尺寸寬高的前提下,取可能的inSampleSize的最大值
14????????while ((halfHeight / inSampleSize) > reqHeight
15????????????????&& (halfWidth / inSampleSize) > reqWidth) {
16????????????inSampleSize *= 2;
17????????}
18????}
19?
20????return inSampleSize;
21}

3. 根據(jù)計(jì)算出的inSampleSize生成Bitmap?

01public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
02????????int reqWidth, int reqHeight) {
03?
04????// 首先設(shè)置 inJustDecodeBounds=true 來獲取圖片尺寸
05????final BitmapFactory.Options options = new BitmapFactory.Options();
06????options.inJustDecodeBounds = true;
07????BitmapFactory.decodeResource(res, resId, options);
08?
09????// 計(jì)算 inSampleSize 的值
10????options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
11?
12????// 根據(jù)計(jì)算出的 inSampleSize 來解碼圖片生成Bitmap
13????options.inJustDecodeBounds = false;
14????return BitmapFactory.decodeResource(res, resId, options);
15}

這里有一點(diǎn)要注意,就是要在第二遍decode之前把inJustDecodeBounds設(shè)置回false。

4. 調(diào)用以上的decodeSampledBitmapFromResource方法,使用自定尺寸的Bitmap

如果你要將一張大圖設(shè)置為一個(gè)100*100的縮略圖,執(zhí)行以下代碼:

1mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

到此,使用decodeResource()方法將一個(gè)大圖解析為小尺寸bitmap的應(yīng)用就完成了。同理,還可以使用decodeStream(),decodeFile()等方法做相同的事,原理是一樣的。

延伸:一個(gè)Bitmap到底占用多大內(nèi)存?系統(tǒng)給每個(gè)應(yīng)用程序分配多大內(nèi)存?

· Bitmap占用的內(nèi)存為:像素總數(shù) * 每個(gè)像素占用的內(nèi)存。在Android中,Bitmap有四種像素類型:ARGB_8888、ARGB_4444、ARGB_565、ALPHA_8,他 們每個(gè)像素占用的字節(jié)數(shù)分別為4、2、2、1。因此,一個(gè)2000*1000的ARGB_8888類型的Bitmap占用的內(nèi)存為 2000*1000*4=8000000B=8MB。

· Android根據(jù)設(shè)備屏幕尺寸和dpi的不同,給系統(tǒng)分配的單應(yīng)用程序內(nèi)存大小也不同,具體如下表(表格取自Android 4.4 Compatibility Definition Document (CDD)):

?

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??

?屏幕尺寸?DPI?應(yīng)用內(nèi)存
?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

總結(jié)

以上是生活随笔為你收集整理的高效使用Bitmaps(一) 大Bitmap的加载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。