本范例實現的是用戶可以通過拍照、相冊獲取圖片,然后進行裁剪,最后將結果保存在IamgeView中。當然你可以選擇將結果同時存放在sd卡中,作為以后的緩存。
思路:
1.通過拍照獲取圖片
進入系統自帶的相機界面——>拍照——>保存在sd卡中——>讀取sd卡的文件進行裁減。PS:裁剪前先判斷是否獲取到圖片了
2.通過系統相冊獲取圖片
進入系統相冊——>找到圖片——>進行裁減。PS:裁剪前線判斷是否獲取到系統的圖片了
接下來貼上實現方法:
1.進入拍照界面或者相冊的方法,獲取信息后回調onActivityResult()方法
public void buttonListener(View v) { switch (v.getId()) { case R.id.fromAlbum_button: // 來自相冊 Intent albumIntent = new Intent(Intent.ACTION_PICK, null); /** * 下面這句話,與其它方式寫是一樣的效果,如果: * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); * intent.setType(""image/*");設置數據類型 * 要限制上傳到服務器的圖片類型時可以直接寫如:"image/jpeg 、 image/png等的類型" */ albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(albumIntent, ALBUM_OK); break; case R.id.fromCamera_button: // 來自相機 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 下面這句指定調用相機拍照后的照片存儲的路徑 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判斷返回結果的標識 break; default: break; } }
2.得到信息,交給onActivityResult()處理。先判斷是否得到信息,如果得到就進行裁剪。
在這里需要注意的是從相冊返回的結果存到的是data里面,拍照后的圖片結果存放的是file文件。由於從相冊取到的圖片可能很大,所以系統會經過一定的壓縮,data得到的圖片有可能失真。具體問題有待實際解決。而拍照后的圖片來源是文件,所以應該不會有什么問題。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println("requestCode = " + requestCode); switch (requestCode) { // 如果是直接從相冊獲取 case ALBUM_OK: //從相冊中獲取到圖片了,才執行裁剪動作 if (data != null) { clipPhoto(data.getData()); } break; // 如果是調用相機拍照時 case CAMERA_OK: // 當拍照到照片時進行裁減,否則不執行操作 if (file.exists()) { clipPhoto(Uri.fromFile(file));//開始裁減圖片 } break; // 取得裁剪后的圖片,這里將其設置到imageview中 case CUT_OK: /** * 非空判斷大家一定要驗證,如果不驗證的話, 在剪裁之后如果發現不滿意, * 要重新裁剪,丟棄 當前功能時,會報NullException */ if (data != null) { setPicToView(data); } break; default: break; } super.onActivityResult(requestCode, resultCode, data); }
3.進行圖片裁剪的方法:
如果在裁剪時返回的圖片很大,系統會強行進行裁剪。
/** * 裁剪圖片方法實現 * @param uri */ public void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面這個crop = true是設置在開啟的Intent中設置顯示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是寬高的比例,這里設置的是正方形(長寬比為1:1) intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪圖片寬高 intent.putExtra("outputX", 200); intent.putExtra("outputY", 200); intent.putExtra("return-data", true); startActivityForResult(intent, CUT_OK); }
4.將裁剪好的圖片設置到ImageView中,同時清除緩存圖片
/** * 保存裁剪之后的圖片數據 將圖片設置到imageview中 * * @param picdata */ private void setPicToView(Intent picdata) { Bundle extras = picdata.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Drawable drawable = new BitmapDrawable(photo); showIv.setImageDrawable(drawable); file.delete();//設置成功后清除之前的照片文件 } }
最后貼上全部的代碼:
package com.kale.picturecut; import java.io.File; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity { // 拍照成功,讀取相冊成功,裁減成功 private final int ALBUM_OK = 1, CAMERA_OK = 2,CUT_OK = 3; private ImageView showIv; private File file; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 定義拍照后存放圖片的文件位置和名稱,使用完畢后可以方便刪除 file = new File(Environment.getExternalStorageDirectory(), "temp.jpg"); file.delete();// 清空之前的文件 showIv = (ImageView) findViewById(R.id.show_imageView); } public void buttonListener(View v) { switch (v.getId()) { case R.id.fromAlbum_button: // 來自相冊 Intent albumIntent = new Intent(Intent.ACTION_PICK, null); /** * 下面這句話,與其它方式寫是一樣的效果,如果: * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); * intent.setType(""image/*");設置數據類型 * 要限制上傳到服務器的圖片類型時可以直接寫如:"image/jpeg 、 image/png等的類型" */ albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(albumIntent, ALBUM_OK); break; case R.id.fromCamera_button: // 來自相機 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 下面這句指定調用相機拍照后的照片存儲的路徑 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判斷返回結果的標識 break; default: break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println("requestCode = " + requestCode); switch (requestCode) { // 如果是直接從相冊獲取 case ALBUM_OK: //從相冊中獲取到圖片了,才執行裁剪動作 if (data != null) { clipPhoto(data.getData()); } break; // 如果是調用相機拍照時 case CAMERA_OK: // 當拍照到照片時進行裁減,否則不執行操作 if (file.exists()) { clipPhoto(Uri.fromFile(file));//開始裁減圖片 } break; // 取得裁剪后的圖片,這里將其設置到imageview中 case CUT_OK: /** * 非空判斷大家一定要驗證,如果不驗證的話, 在剪裁之后如果發現不滿意, * 要重新裁剪,丟棄 當前功能時,會報NullException */ if (data != null) { setPicToView(data); } break; default: break; } super.onActivityResult(requestCode, resultCode, data); } /** * 裁剪圖片方法實現 * @param uri */ public void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面這個crop = true是設置在開啟的Intent中設置顯示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是寬高的比例,這里設置的是正方形(長寬比為1:1) intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪圖片寬高 intent.putExtra("outputX", 200); intent.putExtra("outputY", 200); intent.putExtra("return-data", true); startActivityForResult(intent, CUT_OK); } /** * 保存裁剪之后的圖片數據 將圖片設置到imageview中 * * @param picdata */ private void setPicToView(Intent picdata) { Bundle extras = picdata.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Drawable drawable = new BitmapDrawable(photo); showIv.setImageDrawable(drawable); file.delete();//設置成功后清除之前的照片文件 } } }
權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.per
源碼下載:http://download.csdn.net/detail/shark0017/7964819