調用系統相機/相冊獲取圖片,並裁剪圖片,在百度上找一下能搜到一大堆文章,然而拿過來在真機上跑一下大部分都有問題,根本達不到想要的效果。
爲什麼會拿不到想要的圖片呢,最主要的原因是因爲圖片太大,而獲取的圖片數據是放在Intent中的。而現在手機的像素普遍都是800W+,一張普通的尺寸爲3200*2400px的照片要消耗30MB的內存空間,而一個Intent能傳遞的數據怎麼可能支持這麼大的空間,我測試過一些手機能有1MB已經很開心了。
那麼圖片不放在Intent中,放在哪裏呢。好吧,重要的事情我要說三遍:
“截大圖用Uri,截小圖用Bitmap”“截大圖用Uri,截小圖用Bitmap”
“截大圖用Uri,截小圖用Bitmap”
對待大圖片時應該用Uri返回數據,小圖片才用Bitmap返回數據,不過現在基本都是大圖片,還是放棄Bitmap的方式吧。
裁剪圖片的關鍵代碼:
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
實現代碼如下:
private static final String IMAGE_FILE_LOCATION = "file://" + new File(Environment.getExternalStorageDirectory(), "temp.jpg").getAbsolutePath();//temp file
private Uri imageUri = Uri.parse(IMAGE_FILE_LOCATION);//The Uri to store the big bitmap
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//Log.i(TAG, "onActivityResult() requestCode = " + requestCode + " resultCode = " + resultCode);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case Constant.UPLOAD_LOCAL_IMAGE: // 獲取本地相片
// 獲取本地相片的地址
getImagpath(data);
startPhotoZoom(data.getData());
break;
case Constant.UPLOAD_CAMERA_IMAGE: // 拍攝照片
//Log.i(TAG, "onActivityResult() case Constant.UPLOAD_CAMERA_IMAGE ");
// 獲取原圖
getYuanTu();
break;
case Constant.CAI_JIAN_IMAGE:
Log.i(TAG, "onActivityResult() requestCode = case Constant.CAI_JIAN_IMAGE (imageUri != null) = " + (imageUri != null));
if(imageUri != null){
Bitmap bitmap = decodeUriAsBitmap(imageUri);//decode bitmap
Log.i(TAG, "onActivityResult() CAI_JIAN_IMAGE = bitmap " + bitmap);
if (bitmap != null) {
mImageColorTip.setImageBitmap(bitmap);
}
}
break;
}
}
if (resultCode == Constant.ACTIVIT_FINISH) {
//Log.i(TAG, "onActivityResult() (resultCode == Constant.ACTIVIT_FINISH)");
finish();
}
//super.onActivityResult(requestCode, resultCode, data);
}
private Bitmap decodeUriAsBitmap(Uri uri){
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
Log.w(TAG, "decodeUriAsBitmap()", e);
return null;
}
return bitmap;
}
private void takePicture() {
String sDCard = SDCardPath.checkSDCard();
//Log.i(TAG, "takePicture() (sDCard == null) = " + (sDCard == null));
if (sDCard == null) {
showToast(R.string.text_sd_card_invailable);
} else {
try {
String filePath = SDCardPath.getFilePath(sDCard);
String imagePath = SDCardPath.getImagePath(filePath);
// 下面這句指定調用相機拍照後的照片存儲的路徑
File dir = new File(filePath + "/");
if (!dir.exists()) {
dir.mkdirs();
}
File tmpFile = new File(dir, imagePath);
if (!tmpFile.exists()) {
tmpFile.createNewFile();
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tmpFile));
TakePhotoColorActivity.sImagePath = tmpFile.getAbsolutePath();
startActivityForResult(intent,Constant.UPLOAD_CAMERA_IMAGE);
} catch (IOException e) {
Log.e(TAG, "openAlbum() IOException", e);
}
}
}
private void openAlbum() {
//Log.i(TAG, "openAlbum()");
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent,Constant.UPLOAD_LOCAL_IMAGE);
}
/**
* 獲取原圖的方法
*/
private void getYuanTu() {
//Log.i(TAG, "getYuanTu() PictureColorActivity.sImagePath = " + PictureColorActivity.sImagePath);
File f = new File(TakePhotoColorActivity.sImagePath);
// Log.i(TAG, "getYuanTu() filePath = " + (f == null ? "iOnesNull" : f.getAbsolutePath()));
try {
String imgURL = null;
try {
imgURL = android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), null, null);
} catch (Exception e) {
Log.e(TAG, "getYuanTu() imgURL", e);
}
// Log.i(TAG, "getYuanTu() imgURL = " + imgURL);
Uri u = null;
if (imgURL != null) {
u = Uri.parse(imgURL);
} else {
u = Uri.fromFile(f);
}
// Log.i(TAG, "getYuanTu() uri = " + (u == null ? "iOnesNull" : u.toString()));
startPhotoZoom(u);
} catch (Exception e) {
Log.e(TAG, "getYuanTu()", e);
}
}
/**
* 獲取本地圖片的路徑
*
* @param data
*/
private void getImagpath(Intent data) {
//Log.i(TAG, "getImagpath() PictureColorActivity.sImagePath = " + PictureColorActivity.sImagePath);
Uri originalUri = data.getData(); // 獲得圖片的uri
String[] proj = { MediaStore.Images.Media.DATA };
// 好像是android多媒體數據庫的封裝接口,具體的看Android文檔
// Cursor cursor = managedQuery(originalUri, proj, null, null, null);
Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null);
// 按我個人理解 這個是獲得用戶選擇的圖片的索引值
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 將光標移至開頭 ,這個很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最後根據索引值獲取圖片路徑
String path = cursor.getString(column_index);
TakePhotoColorActivity.sImagePath = path;
}
/**
* 裁剪圖片方法實現
*
* @param uri
*/
public void startPhotoZoom(Uri uri) {
//Log.i(TAG, "startPhotoZoom() PictureColorActivity.sImagePath = " + PictureColorActivity.sImagePath);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 下面這個crop=true是設置在開啓的Intent中設置顯示的VIEW可裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是寬高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
// outputX outputY 是裁剪圖片寬高
// TODO 詳情參考:http://my.oschina.net/ryanhoo/blog/86842
intent.putExtra("outputX", 500);
intent.putExtra("outputY", 500);
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", false);
Log.i(TAG, "startPhotoZoom() (imageUri != null) = " + (imageUri != null));
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, Constant.CAI_JIAN_IMAGE);
}
/** 大圖圖片的路徑 */
private static String sImagePath = "";
public interface Constant {
/**
* 獲取本地圖片
*/
public static final int UPLOAD_LOCAL_IMAGE = 0x0001;
/**
* 獲取相機圖片
*/
public static final int UPLOAD_CAMERA_IMAGE = 0x0002;
public static final String SD_CARD_ROOT = "sdcard";
/**
* 裁剪圖片
*/
public static final int CAI_JIAN_IMAGE=0x0003;
/**
* 回調結束當前界面
*/
public static final int ACTIVIT_FINISH = 0x0004;
/**相機裁剪後的照片*/
public static final int IMAGE_CODE_PATH = 0x0005;
}
如果對你有幫助,不要謝我。大神在這裏:http://my.oschina.net/ryanhoo/blog/86842