美文网首页
Android 图片剪裁保存失败

Android 图片剪裁保存失败

作者: BayRoc | 来源:发表于2023-02-21 15:37 被阅读0次

    调用系统的剪裁方式,保存图片

    • 剪裁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();
            }
        }
    

    相关文章

      网友评论

          本文标题:Android 图片剪裁保存失败

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