Bitmap的高效加載

1 加載方式

BitmaFactory 類提供了四類的加載方法:

  1. decodeFile:從系統文件加載
  2. decodeResource:從資源文件加載
  3. decodeStream:從輸入流加載
  4. decodeByteArray:從字節數組中加載

前二者最終都是調用第三者進行加載的。


2 加載核心

加載的核心就是採用 BitmapFactory.Options 來加載所需尺寸的圖片,其中用到的一個重要的參數爲 inSampleSize(採樣率)。

1 inSampleSize介紹

  1. 當其爲2的時候,採樣後的圖片的寬/高均變爲原來的1/2, 即整體變爲了原來的 1/4
  2. 當其小於1的時候,起作用相當於1,無縮放作用;
  3. 一般情況下,inSampleSize 的取值都是2的指數。若不爲2的指數,那麼系統就會向下取整並選擇一個最接近2的指數來代替;

2 inSampleSize的獲取

  1. BitmapFactory.OptionsinJustDecodeBounds 參數設置爲true,並加載圖片。(此時 BitmapFactory 只會解析圖片的寬/高信息,並不會真正加載圖片)
  2. BitmapFactory.Options 中獲取圖片的原始寬/高信息,對應於outWidthoutHeight的方法。
  3. 根據目標圖片的所需大小計算出inSampleSize
  4. BitmapFactory.OptionsinJustDecodeBounds 參數設置爲false,重新加載圖片。

3 代碼實現

僅以第二種加載方式舉例,其餘的處理方式也類似,但第三種會複雜些。

/**
 * 加載圖片的工具類</br>
 * Created by Administrator on 2016/5/12.
 */
public class LoadBitmapUtil {
    /**
     * 加載資源圖片
     *
     * @param res       資源
     * @param resId     資源圖片Id
     * @param reqWidth  請求的寬度
     * @param reqHeight 請求的高度
     * @return 處理後的Bitmap
     */
    public static Bitmap decodeBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        //First decode whit inJustDecodeBounds=true to check dimention
        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);
    }

    /**
     * 計算inSampleSize
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        //Raw height an 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 keep both height and width larger than the requested
            // height and width.
            while ((halfHeight / inSampleSize) > reqHeight &&
                    (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize = inSampleSize << 2;
            }
        }
        return inSampleSize;
    }

}

方法的調用:

mImageView.setImageBitmap(LoadBitmapUtil.decodeBitmapFromResource(getResources(), R.drawable.test, 100, 100));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章