Android有效的處理Bitmap,減少內存
圖片可能會有不同的大小。在許多情況下,圖片的大小會超出我們需要的大小。例如,我們的Camera應用,我們所拍的照片的大小遠大於屏幕顯示的大小
假如你的應用被限制瞭內存使用,顯而易見,你會選擇加載一個低分辨率的圖片。這張低分辨率的圖片應該匹配屏幕的尺寸。更高分辨率的圖像沒有提供任何可見的好處,但仍占用寶貴的內存,而且由於額外的動態縮放,會帶來額外的性能開銷。
本篇文章教你通過加載一個小尺寸的圖片樣本,來修飾一張大圖,並且沒有超過應用的內存限制。
原文地址https://wear.techbrood.com/training/displaying-bitmaps/load-bitmap.html
獲取圖片的類型尺寸
BitmapFactory這個類提供瞭幾種解碼方法(例如:decodeByteArray(),decodeFile(),decodeResource());我們在加載圖片的額時候,圖片可能有很多種來源,我們選擇合適的一種方法解碼圖片。下面提供瞭方法:為已經創建好的Bitmap重新分配內存,這樣就可以很好的解決內存溢出(OutOfMemory Exception) 的問題。每種解碼方法都有一些標識位,你可以通過配置BitmapFactory.Options這些標識位來實現。設置inJustDecodeBounds的屬性為true的時候,我們解碼的時候不分配內存,返回的Bitmap為null,但是我們設置瞭outWidth,outHeight和outMimeType。這種技術可以預先獲取到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
exceptions,在解碼圖片之前,預先檢查Bitmap的大小,除非你有絕對的把握你的bitmap有合適的大小,並且在內存限制大小范圍之內。
加載縮放的圖片到內存
現在,我們知道瞭圖片的尺寸,我們就可以決定是使用該尺寸的圖片,還是使用另外一個樣本。線面有一些因素是我們要註意的:
估計加載整個圖像所占用的內存 你可以接收的內存使用量和你程序可以使用的內存 你放該圖片的ImageView的尺寸或者其他UI組件的尺寸 屏幕的大小
例如,我們不值得將大小為1024×768 pixel的圖片放到128*96 pixel的縮略圖控件(ImageVIew)裡面。
我們得使用圖片的一個更小的樣本加載到內存裡面,在BitmapFactory.Options裡面設置inSampleSize為true。例如,我們想把一張2048*1536的圖片解碼為隻有1/4大小的圖片512*384,加載到內存裡賣年隻有0.75MB的大小,遠遠小宇原圖12MB的大小(使用ARGB_8888通道的圖片)。這裡有一種計算樣本圖片的方法,根據目標圖片的寬度和高度width和height:
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) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
Note: A power of two value is calculated because the decoder uses a final value by rounding down to the nearest power of two, as per the inSampleSize documentation.
我們在使用該方法的時候,首先設置inJustDecodeBounds
為true,然後我們計算inSample的值,然後設置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); }
這種方法可以幫助我們輕松有效的加載一張100*100的縮略圖片:
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
你也可以通過相同的方法解碼一張從其他路徑獲取到的圖片,通過使用BitmapFactory.decode*
as
need。
下面還有幾篇從android Developer上面翻譯過來的,感覺挺有用的,加個關註吧,(*^__^*)
嘻嘻