http://my.oschina.net/ryanhoo/blog/88242 html
譯者:Ryan Hoo java
來源:https://developer.android.com/develop/index.html
android
譯者按: 在Google最新的文檔中,提供了一系列含金量至關高的教程。由於種種緣由而不爲人知,真是惋惜!Ryan將會細心整理,將之翻譯成中文,但願對開發者有所幫助。 緩存
本系列是Google關於展現大Bitmap(位圖)的官方演示,能夠有效的解決內存限制,更加有效的加載並顯示圖片,同時避免讓人頭疼的OOM(Out Of Memory)。
性能
------------------------------------------------------------------------------------- spa
譯文: .net
圖像能夠有各類各樣的形狀和大小。在不少狀況下,它們每每會比典型的應用UI界面所須要的更大。例如,系統的Gallery程序展現使用Android設備的攝像頭拍攝的照片的分辨率每每要遠高於設備的屏幕密度。
讀取Bitmap(位圖)的尺寸和類型 翻譯
BitmapFactory提供了幾種解碼方式(decodeByteArray(), decodeFile(), decodeResource()等等),以便從多種資源中建立一個Bitmap(位圖)對象。能夠根據你的圖片數據來源選擇最合適的解碼方式。這些方法視圖爲構造Bitmap對象分配內存,所以很容易致使OutOfMemory(OOM)異常。每一種解碼方式都有額外的特徵,你能夠經過BitmapFactory.Options類類指定解碼方法。在解碼圖片的時候設置inJustDecodeBounds屬性爲true,能夠避免內存分配,返回的bitmap對象爲null卻能夠設置outWidth, outHeight和outMimeType。這項技術容許你在建立Bitmap(並分配內存)以前讀取圖片的尺寸和類型。 code
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; |
|
例如,若是最終只是要在ImageView中顯示一張128*96px大小的縮略圖,直接加載1024*768px的圖片是很是不值得的。 orm
爲了告訴解碼器如何對圖像進行採樣,加載更小版本的圖片,須要在BitmapFactory.Options對象中將inSampleSize設置爲true。例如,一張分辨率爲2048*1536px的圖像使用inSampleSize值爲4的設置來解碼,產生的Bitmap大小約爲512*384px。相較於完整圖片佔用12M的內存,這種方式只需0.75M內存(假設Bitmap配置爲ARGB_8888)。這裏有一個方法用來計算基於目標高寬的sample size的值:
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; }
提示:使用2的次冪來設置inSampleSize值可使解碼器執行地更加迅速、更加高效。可是,若是你想在內存或者硬盤上緩存一個調整過大小的圖片,一般仍是解碼到合適的圖片尺寸更加節省空間。
要使用這個方法,首先要使用inJustDecodeBounds爲true來解碼尺寸信息,將options傳遞過去使用新的inSampleSize值再次解碼而且要將inJustDecodeBounds值設置爲false。
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); }
|
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));你能夠根據須要,按照相似的解碼過程,採用適當的BitmapFactory.decode*方法從其餘資源中解碼Bitmap。 |