启动图片裁剪
/** 裁剪原图片路径 */
private String orginImagePath = null;
/**
* 启动图片裁剪
*
* @param imagePath 被剪切图片路径
* @param w 裁剪宽度
* @param h 裁剪高度
*/
public void startUCrop(String imagePath, int w, int h) {
try {
orginImagePath = imagePath;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(FileUtil.getUriForFile(this, new File(imagePath)), "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", w);//宽度比
intent.putExtra("aspectY", h);//高度比
intent.putExtra("outputX", w);//输出图片的宽度
intent.putExtra("outputY", h);//输出图片的高度
intent.putExtra("scale", true);// 保持比例
intent.putExtra("scaleUpIfNeeded", true);
intent.putExtra("return-data", false); // 剪裁后,是否返回 Bitmap
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
//安卓11不指定输出文件路径,直接从data里面获取
cacheImgPath = Uri.fromFile(new File(getAppExternalFileDir() + "/" + System.currentTimeMillis() + ".jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, cacheImgPath);
}
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", false); // 人脸识别,开启后,探测到人脸后会将剪裁框移到人脸上
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_CODE_FOR_CROP);
} else {
// 没有安装所需应用--原图片地址返回
onCropBack(imagePath, "");
CrashReport.postCatchedException(new Exception("图片裁剪调起失败,系统无相关功能"));
}
} catch (Exception e) {
onCropBack(imagePath, "");
CrashReport.postCatchedException(e);
}
}
裁剪完成之后的结果获取
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_FOR_CROP) {
if (resultCode == RESULT_OK) {
try {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
//安卓11版本因为文件私有权限问题,不能走保存路径获取文件方式,需从data里面获取相关文件
onAndroidQCropBack(data);
} else {
if (cacheImgPath != null) {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(cacheImgPath));
String path = getCacheDir() + "/" + System.currentTimeMillis() + ".jpg";
File file = FileUtil.saveToFile(bitmap, path);
Log.d("裁剪保存路径:", path);
if (file != null && file.exists()) {
onCropBack(path, "");
} else {
onCropBack(orginImagePath, "");
CrashReport.postCatchedException(new Exception("onActivityResult: saveToFile fail"));
}
} else {
onCropBack(orginImagePath, "");
Log.i("TAG", "onActivityResult: Uri is null");
CrashReport.postCatchedException(new Exception("onActivityResult: Uri is null"));
}
}
} catch (Exception e) {
//图片裁剪失败,不影响原逻辑且进行上报
onCropBack(orginImagePath, "");
e.printStackTrace();
CrashReport.postCatchedException(e);
}
} else {
onCropBack(orginImagePath, "");
CrashReport.postCatchedException(new Exception("图片裁剪操作失败"));
}
}
}
/**
* 安卓11裁剪返回处理
*
* @param data 返回的数据处理
*/
private void onAndroidQCropBack(@Nullable final Intent data) {
if (data != null && data.getData() != null) {
String imgPath = BitmapUtil.getRealPathFromUri(data.getData(),this);
if(TextUtils.isEmpty(imgPath)){
onCropBack(orginImagePath, "");
CrashReport.postCatchedException(new Exception("安卓11剪切,无法获取剪切之后的图片数据"));
}else{
onCropBack(imgPath, "");
}
} else {
onCropBack(orginImagePath, "");
CrashReport.postCatchedException(new Exception("安卓11剪切,无法获取剪切之后的图片数据"));
}
}
/**
* 图片剪切之后的回调,调用了图片剪切之后实现此方法即可
*
* @param resultUri 剪切之后的图片
* @param msg 剪切失败的信息
*/
public void onCropBack(String resultUri, String msg) {
}
依赖的相关方法:BitmapUtil.getRealPathFromUri()
/**
* 得到绝对地址
*/
public static String getRealPathFromUri(Uri contentUri, Context context) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int columnIndex = 0;
if (cursor != null) {
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(columnIndex);
} else {
return "";
}
} catch (Exception e) {
CrashReport.postCatchedException(e);
return "";
} finally {
if (cursor != null) {
cursor.close();
}
}
}
FileUtil.getUriForFile()
//绝对路径转uri
public static Uri getImageContentUri(Context context, java.io.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 {
throw new NullPointerException();
}
}
}
/**
* 根据文件获取对应的Uri路径
* @param context 上下文
* @param file 对应的文件
* @return 返回的Uri
*/
public static Uri getUriForFile(Context context, File file) {
if (context == null || file == null) {
throw new NullPointerException();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return FileProvider.getUriForFile(context.getApplicationContext(), "这里填FileProvider的authorities", file);
} else {
return getImageContentUri(context,file);
}
}
/**
* 获取应用外部存储文件夹
*/
public static String getAppExternalFileDir() {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.Q) {
File file = context.getExternalFilesDir(null);
if(file!=null){
return file.getAbsolutePath();
}else{
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
}else{
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
}
public static File saveToFile(Bitmap bm, String filePath) {
File result = null;
FileOutputStream writer = null;
try {
result = new File(filePath);
if (result.exists()) {
result.delete();
}
result.getParentFile().mkdirs();
result.createNewFile();
writer = new FileOutputStream(filePath);
bm.compress(Bitmap.CompressFormat.JPEG, 88, writer);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
CrashReport.postCatchedException(new Exception(
"写入文件异常:文件路径->" + filePath
+ "\n文件读取权限->" + (PermissionChecker.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED)
+ "\n文件写入权限->" + (PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED)
+ "\n异常信息->" + e.getMessage()));
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (result.exists() && filePath.length() > 0) {
return result;
}
return null;
}
网友评论