Android从相册以及拍照选取照片,然后裁剪保存遇到的问题

对于从拍照或者相册选取图片然后进行裁剪保存的需求,大部分APP都会遇到,下面是简单地使用方法。

1.使用隐式Intent启动相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);

2.从图库中选择照片
Intent intent = new Intent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent, 2)
3,在onActivityResult()方法中获取返回的数据
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
	if(resultCode == RESULT_OK){
	if(requestCode==1){
		Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/" + fileName));
		cutImage(uri);
	}else if(requestCode==2){
		if(data != null){
		Uri uri=data.getData();
		cutImage(uri);
		}
	}else if(requestCode==REQUEST_TO_PHOTOCUTED){
		Bitmap bitmap = data.getParcelableExtra("data");
	}
	
	}
		
}
4.剪切方法
public void cutImage(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 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 250);//剪裁后X的像素
        intent.putExtra("outputY", 350);//剪裁后Y的像素
//      intent.putExtra("outputFormat", "JPEG");// 返回格式
//      是否去除面部检测, 如果你需要特定的比例去裁剪图片,那么这个一定要去掉,因为它会破坏掉特定的比例。
//      intent.putExtra("noFaceDetection", true);
//      是否要返回值。 一般都要。我第一次忘加了,总是取得空值
        intent.putExtra("return-data", true);
        startActivityForResult(intent, REQUEST_TO_PHOTOCUTED);
    }
上面是大家经常用的拍照剪切的方法,但是,这样写在部分Android手机上就会卡死,崩溃。
原因是在剪切方法中设置了如下属性:intent.putExtra("return-data", true);
通过Intent中的data来传递,当数据过大,在部分手机上时就崩了,(公司一个360手机,这样写总是崩溃)
解决的方法:通过uri来传递。
此时剪切方法中cutImage(Uri uri)中:

 

修改:

intent.putExtra("return-data", false);

增加:

intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra("output",Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/cutphone")));
在onActivityResult(int requestCode, int resultCode, final Intent data)方法数据回调中,通过uri拿到Bitmap
if(requestCode==REQUEST_TO_PHOTOCUTED){
	Bitmap bitmap = MediaStore.Images.Media.getBitmap(baseContext.getContentResolver(),uri));
}
这样修改后,有的手机还是会出现问题,上网查看资料Android7.0后,以前适用的File Uri需要更改为Content Uri。 Android 框架强制执行了 StrictMode API 政策禁止向你的应用外公开 file:// URI。  如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常,如调用系统相机拍照,或裁切照片。 这里我们可以使用 content:// URI类型的Uri,网上有好多的方法都是使用FileProvider类。可以去网上查看,这里我使用的一个方法,把File Uri换成Content Uri
public static Uri getImageContentUri(Context context, File imageFile) {
 String filePath = imageFile.getAbsolutePath();
 Cursor cursor = context.getContentResolver().query(
 MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
 new String[] { MediaStore.Images.Media._ID },
 MediaStore.Images.Media.DATA + "=? ",
 new String[] { filePath }, null);

 if (cursor != null && cursor.moveToFirst()) {
 int id = cursor.getInt(cursor
 .getColumnIndex(MediaStore.MediaColumns._ID));
 Uri baseUri = Uri.parse("content://media/external/images/media");
 return Uri.withAppendedPath(baseUri, "" + id);
 } else {
 if (imageFile.exists()) {
 ContentValues values = new ContentValues();
 values.put(MediaStore.Images.Media.DATA, filePath);
 return context.getContentResolver().insert(
 MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
 } else {
 return null;
 }
 }
}
通过这个方法。把从相册,拍照获取的uri转换成Content Uri,再进行剪切,然后保存在File Uri中,在回调数据中拿到;

具体代码:

public void onActivityResult(int requestCode, int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
	if(resultCode == RESULT_OK){
	if(requestCode==1){
		Uri uri = getImageContentUri(this,new File(Environment.getExternalStorageDirectory(), "/" + fileName))
		cutImage(uri);
	}else if(requestCode==2){
		if(data != null){
		Uri uri=getImageContentUri(baseContext,new File(BitmapHelper.getImageAbsolutePath(baseContext,data.getData())));
		cutImage(uri);
		}
	}else if(requestCode==REQUEST_TO_PHOTOCUTED){
		Bitmap bitmap = MediaStore.Images.Media.getBitmap(baseContext.getContentResolver(),Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/cutphone")));
	}
	
	}

public void cutImage(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", 250);//剪裁后X的像素
        intent.putExtra("outputY", 350);//剪裁后Y的像素
        intent.putExtra("output",Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/cutphone"))); //保存路径me
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, REQUEST_TO_PHOTOCUTED);
    }

















  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值