天天看點

關于Android中圖檔壓縮(上傳前的處理)

 這幾天做的項目中有個圖檔上傳子產品,上傳部分用的是xutils架構上傳前自動對圖檔進行了壓縮處理。但使用者還是一直反應上傳特别慢,主要是因為現在手機一般一張圖檔都特别大,沒處理或者處理不夠的話會嚴重影響使用者體驗,于是研究了下Android的圖檔壓縮部分:

一:圖檔壓縮相關的概念(參考:http://blog.csdn.net/cherry609195946/article/details/9264409)

1.Android中圖檔的存在形式有三種:

    a.File的形式存在于硬碟中。

    b.在記憶體中存在有兩種形式,一種是流,一種是bitmap

2.廣義所說的圖檔壓縮包括兩種方式:品質壓縮和大小壓縮

   品質壓縮:通說說就是将圖檔儲存為File時候進行壓縮,讓其大小變小。主要用在網絡上傳圖檔時候友善上傳伺服器。但其記憶體中大小并未改變,甚至      會變大。

   大小壓縮:圖檔從本地讀取時候轉換成bitmap過程中進行壓縮處理,通過設定采樣率減少圖檔的像素,達到對記憶體中bitmap進行壓縮,減少占用記憶體

二:壓縮部分的代碼

 品質壓縮:

<span style="font-size:14px;">private Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//品質壓縮方法,這裡100表示不壓縮,把壓縮後的資料存放到baos中
        int options = 100;
        while ( baos.toByteArray().length / 1024>100) {    //循環判斷如果壓縮後圖檔是否大于100kb,大于繼續壓縮        
            baos.reset();//重置baos即清空baos
            options -= 10;//每次都減少10
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//這裡壓縮options%,把壓縮後的資料存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把壓縮後的資料baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream資料生成圖檔
        return bitmap;     
		//傳回的bitmap所占記憶體并沒減少。。
		
		 // Generate compressed image file  儲存成File形式
        FileOutputStream fos = new FileOutputStream(outPath);
        fos.write(os.toByteArray());
        fos.flush();
        fos.close();
    }</span>           

 大小壓縮;

   a.計算壓縮比例

<span style="font-size:14px;">public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
     final int height = options.outHeight;    //圖檔的原始高 寬
     final int width = options.outWidth;
     int inSampleSize = 1;
     if (height > reqHeight || width > reqWidth) {
             final int heightRatio = Math.round((float) height/ (float) reqHeight);
             final int widthRatio = Math.round((float) width / (float) reqWidth);
             inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
     }
        return inSampleSize;
     }</span>           

   b.開始壓縮

   // 根據路徑獲得圖檔并壓縮,傳回bitmap用于顯示

<span style="font-size:14px;">	public static Bitmap getSmallBitmap(String filePath) {
			final BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;   
			//inJustDecodeBounds設定為true,可以不把圖檔讀到記憶體中,但依然可以計算出圖檔的大小
			BitmapFactory.decodeFile(filePath, options);


			// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, 480, 800);


			// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		//此時傳回的就是已經被壓縮的bitmap。。可以用于顯示在界面上
		return BitmapFactory.decodeFile(filePath, options);
		}</span>           

總結:一般圖檔壓縮處理是先進行大小壓縮,在進行品質壓縮互相結合方式。

Thanks:

http://www.360doc.com/content/14/0428/17/11800748_372972179.shtml