美文网首页
关于调用系统图片裁剪功能

关于调用系统图片裁剪功能

作者: 初见soulmate | 来源:发表于2021-02-22 09:24 被阅读0次

启动图片裁剪

   /** 裁剪原图片路径 */
    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;
    }

相关文章

网友评论

      本文标题:关于调用系统图片裁剪功能

      本文链接:https://www.haomeiwen.com/subject/tplhfltx.html