调用系统的剪裁方式,保存图片
-
剪裁app私有路径的图片时,可以将剪裁后的图片保存在似有路径,但是在剪裁系统相册中的图片时,在sdk>=30时,无法保存到app似有路径,需要添加判断当
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
时保存到公共目录下(需要申请读写权限) -
打开相机
private Uri cameraContentUri;//拍照照片的Uri
private String contentURl;//当前保存的图片路径
private void openCamera() {
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (!checkPermissions(permissions)) {
requestPermission(permissions, 102);
} else {
Intent cameraintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraintent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
// 指定调用相机拍照后照片的储存路径
contentURl = PathUtils.imagePath + File.separator + System.currentTimeMillis() + ".jpg";
File file = new File(contentURl);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cameraContentUri = FileProvider.getUriForFile(UserSignProtocolActivity.this, UserSignProtocolActivity.this.getApplicationContext().getPackageName() + ".provider", file);
cameraintent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
cameraContentUri = Uri.fromFile(file);
}
cameraintent.putExtra(MediaStore.EXTRA_OUTPUT, cameraContentUri);
startActivityForResult(cameraintent, OPEN_CAMERA);
}
}
- 打开相册
/**
* 打开相册
*/
private void openPhotoAlbum() {
//先判断有没有存储权限
if (!checkPermissions(PERMISSIONS_STORAGE)) {
requestPermission(PERMISSIONS_STORAGE, 101);
return;
}
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_GALLERY
startActivityForResult(intent, OPEN_PHOTO);
}
- 剪裁
private Uri cropUri;//剪裁后的Uri
/**
* 裁剪
*
* @param uri 要裁剪的图片Uri
* @param flag true:相册中选取裁剪,false:相机拍照后裁剪
*/
private void crop(Uri uri, boolean flag) {
// 裁剪图片意图
try {
Intent intent = new Intent("com.android.camera.action.CROP");
contentURl = PathUtils.imagePath + File.separator + System.currentTimeMillis() + ".jpg";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && flag) {
//SDK大于30,系统相册的剪裁不能访问似有路径,需要保存到公共路径种
contentURl = PathUtils.SYSTEMPIMGPATH + File.separator + System.currentTimeMillis() + ".jpg";
}
File cropFile = new File(contentURl);
if (flag) {
//相册选图片裁剪:注意到此处使用的file:// uri类型.
cropUri = Uri.fromFile(cropFile);
} else {
//相机拍完后裁剪
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cropUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", cropFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
cropUri = Uri.fromFile(cropFile);
}
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", UIUtils.dip2px(300));
intent.putExtra("aspectY", UIUtils.dip2px(185));
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", UIUtils.dip2px(300));
intent.putExtra("outputY", UIUtils.dip2px(185));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", false);
intent.putExtra("output", cropUri);
//重要!!!添加权限,不然裁剪完后报 “保存时发生错误,保存失败”
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, cropUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
ComponentName componentName = intent.resolveActivity(getPackageManager());
if (componentName != null) {
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
startActivityForResult(intent, CROP_PICTURE);
}
} catch (Exception e) {
String s = e.getMessage().toString();
}
}
- 回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OPEN_PHOTO) {
if (data != null) {
Uri data1 = data.getData();
if (data1 != null) {
crop(data1, true);//调用剪裁
}
}
} else if (requestCode == CROP_PICTURE) {//剪裁完成
localre(contentURl);
} else if (requestCode == OPEN_CAMERA) {
crop(cameraContentUri, false);//调用剪裁
}
}
- 本来觉得已经解决了,没想到经过测试小姐姐不懈的努力后,又碰到了问题.鸿蒙系统在获取权限的时候只给到了媒体权限,并没有获取到文件存储的权限,所以剪裁后保存到公共目录中的图片无法获取到.然后尝试使用与相机剪裁同样的URI处理方式,发现好用,那就稍微改一改!
private Uri cropUri;//剪裁后的Uri
/**
* 裁剪
*
* @param uri 要裁剪的图片Uri
*/
private void crop(Uri uri) {
// 裁剪图片意图
try {
Intent intent = new Intent("com.android.camera.action.CROP");
contentURl = PathUtils.imagePath + File.separator + System.currentTimeMillis() + ".jpg";
File cropFile = new File(contentURl);
//在7.0以上跨文件传输uri时候,需要用FileProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cropUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", cropFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
cropUri = Uri.fromFile(cropFile);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", UIUtils.dip2px(300));
intent.putExtra("aspectY", UIUtils.dip2px(185));
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", UIUtils.dip2px(300));
intent.putExtra("outputY", UIUtils.dip2px(185));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", false);//是否返回裁剪后图片的Bitmap
intent.putExtra("output", cropUri);
//重要!!!添加权限,不然裁剪完后报 “保存时发生错误,保存失败”
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, cropUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
ComponentName componentName = intent.resolveActivity(getPackageManager());
if (componentName != null) {
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
startActivityForResult(intent, CROP_PICTURE);
}
} catch (Exception e) {
String s = e.getMessage().toString();
}
}
网友评论