原文:http://www.zhaoweihua.name/android-cropimage-149.html
有時候我們開發的應用中需要圖片剪切功能,比如提供聯系人頭像選擇並剪切上傳,或許很多人實現起來會比較繁瑣,這里我提取了Android系統自帶的剪切功能,和直接通過Intent方式調用系統Camera程序的方式比起來,這個會具有更好的兼容性。先看截圖:
首先還是先說下怎樣通過Intent直接調用系統的圖片剪切功能,在android1.6及以前的系統中,可以通過以下代碼以startActivityForResult方式發送一個特定的Intent,然后在onActivityResult接收返回的圖片數據:

Intent intent =newIntent("com.android.camera.action.CROP"); intent.setClassName("com.android.camera","com.android.camera.CropImage");File file =newFile(filePath);Uri uri =Uri.fromFile(file); intent.setData(uri); intent.putExtra("crop","true"); intent.putExtra("aspectX",1); intent.putExtra("aspectY",1); intent.putExtra("outputX",96); intent.putExtra("outputY",96); intent.putExtra("noFaceDetection",true); intent.putExtra("return-data",true); startActivityForResult(intent, REQUEST_CROP_ICON);
在Android1.6系統之后,uri不讓傳file:///了,只能傳圖庫中的圖片:
Intent intent =newIntent("com.android.camera.action.CROP"); intent.setData(data.getData());//data是圖庫選取文件傳回的參數 intent.putExtra("crop","true"); intent.putExtra("aspectX",1); intent.putExtra("aspectY",1); intent.putExtra("outputX",96); intent.putExtra("outputY",96); intent.putExtra("noFaceDetection",true); intent.putExtra("return-data",true); startActivityForResult(intent, REQUEST_CROP_ICON);
這兩只方式都是通過startActivityForResult方式來獲取數據返回的,在onActivityResult中可以通過下面代碼來得到返回經過剪切處理的圖片數據:
//先判斷是否為RESULT_OK,然后再判斷REQUEST_CROP_ICON,代碼省略。Bundle extras = data.getExtras();if(extras !=null){Bitmap photo = extras.getParcelable("data");ByteArrayOutputStream stream =newByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG,75, stream);//將流寫入文件或者直接使用}
現在來看看對CropImage提取后的項目結構:
整個圖片剪切功能的實現代碼在crop包下,ImageCropActivity.java為測試應用的啟動界面,CropUtil.java為工具類,代碼的主要邏輯是先點擊按鈕,然后從相冊選擇一張圖片,再調用剪切程序進行剪切並獲取處理后的數據(也可以將存儲卡中的任意圖片格式的文件直接傳給剪切程序進行處理),這里有幾點要注意的:
1.在AndroidMainfast文件中注冊activity :
<activityandroid:name="name.zhaoweihua.crop.CropImage"/><!--注意包名需與你的項目一直-->
2.添加對應的存儲卡讀寫權限,一般相機拍攝的照片像素都比較高,在圖片處理前先對圖片大小和質量進行了壓縮處理,以避免網絡上傳中耗費太大流量,以及圖片操作內存溢出的可能性,如果不需要,大家可以在代碼中去除相關代碼。
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
3.另外,注意修改布局文件cropimage.xml中View的路徑和項目中包的路徑一致:
<viewclass="name.zhaoweihua.crop.CropImageView"android:id="@+id/image"android:background="#55000000"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_x="0dip"android:layout_y="0dip"/>
接下來就是代碼使用,直接通過文件File來構造Uri然后傳給Intent,再startActivityForResult,和Android1.6版調用系統剪切功能類似:
//調用CropImage類對圖片進行剪切Intent intent =newIntent(this, name.zhaoweihua.crop.CropImage.class);Bundle extras =newBundle(); extras.putString("circleCrop","true"); extras.putInt("aspectX",200); extras.putInt("aspectY",200);//這里的File文件可以是通過系統相冊選取的,也可以是位於存儲卡中任何一副圖片文件 intent.setDataAndType(Uri.fromFile(f),"image/jpeg"); intent.putExtras(extras); startActivityForResult(intent, PHOTO_CROP_DATA);
然后從onActivityResult中獲取數據,這里就不多說了,大家可以下載項目代碼研究。
測試項目下載CropImage

