1. 程式人生 > >針對大圖轉Bitmap的壓縮處理

針對大圖轉Bitmap的壓縮處理

public  Bitmap setBitmapFromDisk(){
        BitmapFactory.Options options=new BitmapFactory.Options();
        //設定只加載圖片的格式尺寸資訊到記憶體,不載入具體的圖片位元組。
        options.inJustDecodeBounds=true;
        Bitmap bitmap=BitmapFactory.*decodeResource* 
                      (getResources(),R.drawable.*big*,options);
        //獲取圖片的高度和寬度
        int  height=options.outHeight;
        int  width=options.outWidth;
        //獲取圖片的型別
        String imageType = options.outMimeType;
        Log.*d*("imageTest",height+"    "+width+"   "+imageType);
        System.*out*.println(height+"    "+width+"   "+imageType);
        //長&&寬壓縮的比例,記憶體佔用的比例關係是平方倍
        options.inSampleSize=2;
        options.inJustDecodeBounds=false;
        bitmap=BitmapFactory.*decodeResource*(getResources(),R.drawable.*big*,options);
       return bitmap;
    }

1. 獲取原圖片尺寸

通常我們使用BitmapFactory.decodeResource()方法來從資原始檔中讀取一張圖片並生成一個Bitmap。但如果使用一個BitmapFactory.Options物件,並把該物件的inJustDecodeBounds屬性設定為true,decodeResource()方法就不會生成Bitmap物件,而僅僅是讀取該圖片的尺寸和型別資訊:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
intimageHeight = options.outHeight;
intimageWidth = options.outWidth;
String imageType = options.outMimeType;

2. 根據原圖尺寸和目標區域的尺寸計算出合適的Bitmap尺寸

BitmapFactory.Options類有一個引數inSampleSize,該引數為int型,他的值指示了在解析圖片為Bitmap時在長寬兩個方向上畫素縮小的倍數。inSampleSize的預設值和最小值為1(當小於1時,解碼器將該值當做1來處理),且在大於1時,該值只能為2的冪(當不為2的冪時,解碼器會取與該值最接近的2的冪)。

例如,當inSampleSize為2時,一個2000 x 1000的圖片,將被縮小為1000 x 500,相應地,它的畫素數和記憶體佔用都被縮小為了原來的1/4:

publicstatic int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // 原始圖片的寬高
    finalint height = options.outHeight;
    finalint width = options.outWidth;
    intinSampleSize = 1;

    if(height > reqHeight || width > reqWidth) {

        finalint halfHeight = height / 2;
        finalint halfWidth = width / 2;

        // 在保證解析出的bitmap寬高分別大於目標尺寸寬高的前提下,取可能的inSampleSize的最大值
        while((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    returninSampleSize;
}

3. 根據計算出的inSampleSize生成Bitmap

publicstatic Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        intreqWidth, int reqHeight) {

    // 首先設定 inJustDecodeBounds=true 來獲取圖片尺寸
    finalBitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // 計算 inSampleSize 的值
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // 根據計算出的 inSampleSize 來解碼圖片生成Bitmap
    options.inJustDecodeBounds = false;
    returnBitmapFactory.decodeResource(res, resId, options);
}

這裡有一點要注意,就是要在第二遍decode之前把inJustDecodeBounds設定回false,生成需要尺寸的bitmap。

4. 呼叫以上的decodeSampledBitmapFromResource方法,使用自定尺寸的Bitmap

如果你要將一張大圖設定為一個100*100的縮圖,執行以下程式碼:

mImageView.setImageBitmap(decodeSampledBitmapFromResource(
getResources(), R.id.myimage, 100,100));

到此,使用decodeResource()方法將一個大圖解析為小尺寸bitmap的應用就完成了。同理還可以使用decodeStream()、decodeFile()等方法做相同的事,原理是一樣的。