调用系统相机/相册获取图片,并裁剪图片,在百度上找一下能搜到一大堆文章,然而拿过来在真机上跑一下大部分都有问题,根本达不到想要的效果。
为什么会拿不到想要的图片呢,最主要的原因是因为图片太大,而获取的图片数据是放在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