Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android BitmapFactory圖片壓縮處理(大位圖二次采樣壓縮處理)

Android BitmapFactory圖片壓縮處理(大位圖二次采樣壓縮處理)

編輯:關於Android編程

Android實際開發中,在加載大量圖片的時候,比如ViewPager、GridView、ListView中,加載了大量的比較大圖片就容易出現OOM(內存溢出)的異常,這是因為一個應用的最大內存使用只有16M,超過了這個值,就會出現OOM。所以我們實際開發中,要想避免OOM出現就要對相應的圖片進行壓縮處理。

本文即使用了BitmapFactory和BitmapFactory.Option這兩個類,對圖片進行相應的尺寸壓縮處理。經測試,成功解決了未壓縮圖片之前出現的OOM異常。

實現效果圖:

本Demo使用的圖片大小為2M左右(壓縮以前)。

我壓縮圖片之前:

我這裡將壓縮的代碼注釋掉了:

\

運行結果:

\

進行壓縮處理後的圖片:

壓縮後圖片大小為:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140718/2014071809444262.jpg" alt="\">

大約為98KB


運行結果:

\

源代碼:

\

布局文件:

activity_main:



    
    


list_item.xml:




    

    



MainActivity:

package com.android_bitmapcompressdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView listView;
	private MyAdapter adapter;
	private int[] items = new int[] { R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
			R.drawable.pc, R.drawable.pc };
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		listView = (ListView) findViewById(R.id.listView);
		adapter = new MyAdapter(this, items);
		listView.setAdapter(adapter);
		adapter.notifyDataSetChanged();
	}
}


ListView適配器:MyAdapter:

package com.android_bitmapcompressdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {
	private int[] items = new int[] {};
	private Context context;
	private String TAG = "zhongyao";
	private Bitmap bitmap = null;

	public MyAdapter(Context context, int[] items) {
		this.context = context;
		this.items = items;
	}

	@Override
	public int getCount() {
		return items.length;
	}

	@Override
	public Object getItem(int position) {
		return items[position];
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
			holder = new ViewHolder();
			holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
			holder.textView = (TextView) convertView.findViewById(R.id.textView);
			
			convertView.setTag(holder);
		}else {
			holder = (ViewHolder) convertView.getTag();
		}
		
			bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(
					context.getResources(), R.drawable.pc, 100, 100);
			Log.d(TAG, "壓縮之後的圖片大小為:" + bitmap.getByteCount());
		holder.imageView.setImageBitmap(bitmap);
		holder.textView.setText("圖片"+position);
		
		return convertView;
	}

	class ViewHolder {
		ImageView imageView;
		TextView textView;
	}
}

BitmapCompressTools(壓縮工具類):

package com.android_bitmapcompressdemo;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

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

		// 給定的BitmapFactory設置解碼的參數
		final BitmapFactory.Options options = new BitmapFactory.Options();
		// 從解碼器中獲取原始圖片的寬高,這樣避免了直接申請內存空間
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);

		// 壓縮完後便可以將inJustDecodeBounds設置為false了。
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}

	/**
	 * 指定圖片的縮放比例
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */

	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 halfHeight = height / 2;
//			// final int halfWidth = width / 2;
//			// while ((halfHeight / inSampleSize) > reqHeight
//			// && (halfWidth / inSampleSize) > reqWidth) {
//			// inSampleSize *= 2;
//			// }
//			
			/**
			 * 壓縮方式一
			 */
			// 計算壓縮的比例:分為寬高比例
			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;
	}
}

達到了預期效果,但是寫到這裡滑動ListView的時候,還是會有些卡頓,有這方面解決經驗的可以給我留言討論。

源代碼已上傳到資源中,可到我的資源中下載。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved