高效地加載圖片(一) 高效地加載大圖

1.Read Bitmap Dimensions and Type 讀取圖片的尺寸和類型 java

//建立一個Options,用於保存圖片的參數 

BitmapFactory.Options options = new BitmapFactory.Options(); 

//設置是否只讀取圖片的參數信息 

options.inJustDecodeBounds = true; 

//因爲inJustDecodeBounds被設置爲了true,此處只會得到圖片的參數信息 

//而不會讀取到Bitmap對象,也就不會佔用內存 

BitmapFactory.decodeResource(getResources(), R.id.myimage, options); 

//得到圖片的寬高以及類型 

int imageHeight = options.outHeight; 

int imageWidth = options.outWidth; 

String imageType = options.outMimeType; 

爲了不java.lang.OutOfMemory異常,在將一張圖片解析爲Bitmap對象以前,必定要檢查它的尺寸. spa

2.Load a Scaled Down Version into Memory 加載通過縮放的圖片到內存中 code

既然咱們已經知道了圖片的尺寸,咱們就知道是否有必要將原圖加載到內存中.咱們能夠有選擇的將圖片通過縮放後再加載到內存中. 對象

須要考慮的因素有如下幾點: 圖片

1.預估加載原圖須要的內存大小 內存

2.你願意給這張圖片分配的內存大小 ci

3.要顯示這張圖片的控件的尺寸大小 get

4.手機屏幕的大小以及當前設備的屏幕密度 it

舉例說明,若是你想要顯示一張128×96像素的縮略圖,則加載一張1024×768像素的圖片是沒有必要的. io

爲了告訴解碼器去加載一張通過縮放的圖片,須要設置BitmapFactory.Options的inSampleSize參數.

例如:一張圖片的原始大小是2048×1536,若是將inSampleSize設置爲4,則此時加載的圖片大小爲512×384,加載通過縮放後的圖片只須要0.75MB的內存控件而不是加載全圖時須要的12MB.

如下是一個計算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;
	// 默認縮放比例爲1
    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.
		// 計算inSampleSize的值,該值是2的次方,而且可以保證圖片的寬高大於指定的寬高
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

要想使用上述方法,首先要講inJustDecodeBounds設置爲true,讀取到圖片的尺寸信息,再通過計算獲得的inSampleSize去解析圖片

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
	// 此處將inJustDecodeBounds設置爲true,則只解析圖片的尺寸等信息,而不生成Bitmap
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
	// 此處計算須要的縮放值inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
	//將inJustDecodeBounds設置爲false,以便於解析圖片生成Bitmap
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}
相關文章
相關標籤/搜索