1. 程式人生 > >Android筆記之 圖片自由裁剪

Android筆記之 圖片自由裁剪

前言——專案中需要用到對使用者頭像的裁剪和上傳功能。關於裁剪,一開始是想自己來做,但是覺得這個東西應該谷歌有開發吧,於是一搜索官方文件,果然有。於是,就果斷無恥地用了Android自帶有關於照片的自由裁剪。因為時間太緊,雖然不太華麗,但是勝在能用,節省時間嘛。


具體是通過 Intentaction來實現的。

關鍵程式碼如下:

public void imageCut(Uri uri) {

	Intent intent = new Intent("com.android.camera.action.CROP");
	intent.setDataAndType(uri, "image/*");
	//開啟裁剪功能
	intent.putExtra("crop", "true");
	//設定寬高的比例
	intent.putExtra("aspectX", 1);
	intent.putExtra("aspectY", 1);
	//設定裁剪圖片寬高
	intent.putExtra("outputX", 100);
	intent.putExtra("outputY", 100);
	//要求返回資料
	intent.putExtra("return-data", true);
	startActivityForResult(intent, 100);
	}

返回資料後直接在onActivityResult裡對返回的圖片資料進行顯示就行了,這裡由於剪下後的圖片較小,個人覺得應該不用考慮OOM的問題,問題是,在呼叫自帶的裁剪功能的時候,由於沒看原始碼,所以不知道在調整裁剪框的時候,顯示的那副圖片有沒有進行壓縮,如果沒有進行壓縮,那麼當圖片很大的時候,載入起來就很容易出現OOM了,明顯對此由於是呼叫官方的API,我沒有方法去解決它。唯一的辦法就是不用它,而是自己去寫一個,就可以避免這個問題。利用如下的程式碼進行壓縮,很好地避免OOM問題。


/*
	 * 壓縮圖片,返回的是壓縮後的照片
	 */
	public static Bitmap revitionImage(String path,int size){
		Bitmap bitmap = null;
		try {
			//先用圖片路徑開啟圖片檔案,緩衝到一個快取輸入流中
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(
				new File(path)));
			//用引數代表變數來記錄當前照片的資訊,比如圖片大小
			BitmapFactory.Options options = new BitmapFactory.Options();
			//把inJustDecodeBounds設定為true,則完全不用分配記憶體就可以得到給點陣圖檔案bitmap的資訊,
			//如此得到大小後,就可以對其進行7壓縮,然後在記憶體中生成一個更小的bitmap,節省了記憶體
			options.inJustDecodeBounds = true;
			//譯碼點陣圖檔案,只為了得到原圖的資訊
			BitmapFactory.decodeStream(in
				,null,options);
			//記得關閉流
			in.close();
			int i = 0;
			
			while(true){
				//右移i位是因為下面的pow取一半了,新生成的圖片是原來的二分之一
				if (((options.outWidth >> i)<=size) && ((options.outHeight >> i) <=size)) {
					//這時候應取得照片了
					in = new BufferedInputStream(new FileInputStream(new File(path)));
					//pow是次方方法,2的i次方,inSampleSize圖片均分取樣值,例如
					//inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. 
					options.inSampleSize = (int)Math.pow(2.0, i);
					//這時候的圖片已經符合我們設定的256大小了,所以要在設定false,允許輸出,建立圖片
					//真正地生成一個有畫素的,經過縮放的bitmap
					options.inJustDecodeBounds = false;
					bitmap = BitmapFactory.decodeStream(in,null,options);//獲得n分之一原圖,小於256*256
					break;
				}else {
					i++;
				}
			}
			
		} catch (IOException e) {
			Log.i(TAG, "壓縮圖片出錯"+e.toString());
		}
		return bitmap;
	}

最後只能先用著了,有時間再深究或者自己折騰一個。下面是效果圖,看著還行。




下面是一個關於本主題的DEMO。有需要的童鞋可以去看看。