Android如何高效顯示較大的Bitmaps
一、高效加載較大的Bitmaps
圖片有各種形狀和各種大小,在很多情況下,圖片的實際大小都比圖片在應(yīng)用中所顯示的大小要大的多,比如Android系統(tǒng)自帶的 Gallery 應(yīng)用顯示的照片實際的分辨率通常比手機設(shè)備的密度要高很多
考慮到我們是在開發(fā)一款內(nèi)存使用受限的應(yīng)用,理想的情況下,我們只是想把一個低分辨率版本的位圖載入內(nèi)存,一般來說這個低分辨率版本的位圖要跟UI元件實際需要顯示的大小相符。一張高分辨率的圖片并不會給我們帶來任何明顯的好處,但卻會占用寶貴的內(nèi)存資源和產(chǎn)生額外的性能開銷
二、獲取Bitmap的尺寸大小和類型
BitmapFactory 類為我們提供了幾種decoding方法(decodeByteArray(), decodeFile(),decodeResource(), etc)來從不同的來源創(chuàng)建出 Bitmap ,如何選擇最恰當?shù)膁ecode方法取決于你的圖片數(shù)據(jù)來源,這些方法都會去嘗試申請內(nèi)存來構(gòu)建Bitmap對象,所有很容易就會導致一個OutOfMemory 異常,每種類型的decode方法都有額外的簽名來讓你通過 BitmapFactory.Options 類來指定decoding選項,當我們decoding的時候把inJustDecodeBounds 屬性設(shè)置為true 可以避免申請內(nèi)存,雖然會返回一個null Bitmap對象 ,但是會為我們傳入的BitmapFactory.Options 對象設(shè)置 outWidth, outHeight and outMimeType 等屬性的值,這個技術(shù)可以讓你在構(gòu)建Bitmap對象之前事先知道它的大小和類型
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType;
為了避免java.lang.OutOfMemory 異常,在decoding Bitmap之前你有必要去檢測Bitmap的大小和類型,除非你真的是非常清楚你要decoding的Bitmap的大小,還有這個大小要適合當前應(yīng)用內(nèi)存環(huán)境
三、載入‘縮小版'的Bitmap到內(nèi)存
現(xiàn)在我們已經(jīng)知道了Bitmap的大小,這將有助于我們來決策是載入整張Bitmap還是載入'縮小版'的Bitmap,這里有一些因素需要進行考慮:
1、載入整張圖片預(yù)計要使用多少內(nèi)存
2、在考慮到其它方面內(nèi)存需要的情況下,你想把多少數(shù)量的內(nèi)存給Bitmap使用:
3、用于顯示Bitmap的 ImageView 控件或其它UI元件的大小
4、當前設(shè)備屏幕的大小和密度
例如,一點都不值得載入1024x768 像素的圖片到內(nèi)存中,而最終只在128x96 像素大小的 ImageView 控件上顯示
我們應(yīng)該告訴decoder,圖像需要進行抽樣,載入一個更小號的Bitmap到內(nèi)存中,設(shè)置 BitmapFactory.Options 對象的 inSampleSize 屬性為true 。例如,一張分辨率為2048x1536 像素的圖片,如果decode的時候把inSampleSize 設(shè)置為4,那么得到的最終圖片的大小大約為512x384 ,載入內(nèi)存耗費0.75M而不是載入整張時的12M (假設(shè)位圖的配置為 ARGB_8888) ,下面有一個在目標高和寬基礎(chǔ)上計算inSampleSize 的方法
public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize; }
NOTE : inSampleSize 值是2的冪的話,對于decoder來說會更快和更高效。然而,如果你想把調(diào)整過大小的位圖緩存到內(nèi)存或硬盤上時,依然非常有意義decoding最合適的位圖大小,這樣有助于節(jié)省內(nèi)存或節(jié)省硬盤空間
下面是一個獲取位圖的方法
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
這個方法可以很容易的做到在任意顯示尺寸大小的UI元件中去載入一張位圖
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
在其他的BitmapFactory.decode* 系列的decode方法中以上獲取位圖的技術(shù)也是需要的。
以上就是本文的全部內(nèi)容,希望對大家學習Android軟件編程有所幫助。
- Android Bitmap詳細介紹
- Android界面 NotificationManager使用Bitmap做圖標
- 解析Android開發(fā)優(yōu)化之:對Bitmap的內(nèi)存優(yōu)化詳解
- Android Bitmap和Drawable相互轉(zhuǎn)換的簡單代碼
- android bitmap compress(圖片壓縮)代碼
- android保存Bitmap圖片到指定文件夾示例
- android中Bitmap的放大和縮小實例代碼
- Android Activity之間傳遞圖片(Bitmap)的方法
- android將Bitmap對象保存到SD卡中的方法
- Android中使用BitmapShader類來制作各種圖片的圓角
相關(guān)文章
Android getActivity()為空的問題解決辦法
這篇文章主要介紹了Android getActivity()為空的問題解決辦法的相關(guān)資料,導致apk空指針崩潰問題,很嚴重的問題,為了解決這問題,上網(wǎng)搜索了很多資料,需要的朋友可以參考下2017-07-07Android 模仿iPhone列表數(shù)據(jù)View刷新動畫詳解
本文主要介紹Android 模仿iPhone列表數(shù)據(jù)view 刷新動畫的資料,這里整理詳細的資料,并附示例代碼及實現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-09-09