关于大图片裁剪在华为等手机上无法使用问题

项目中我们在进行图片上传时,往往不是选择好图片直接上传就好,而是需要进行一些操作,比如裁剪。通常我的的裁剪是这样的。

public void startPhotoZoom(Uri uri, int width, int height) {
        // 裁剪图片
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        //传进来的宽高(比例aspectX aspectY)裁剪
        if(android.os.Build.MODEL.contains("HUAWEI")) {
            //华为特殊处理 不然会显示圆
            if (width != 0 && height != 0) {
                intent.putExtra("aspectX", 9998);
                intent.putExtra("aspectY", 9999*height/width);
            } else {
                intent.putExtra("aspectX", 9998);
                intent.putExtra("aspectY", 9999);
            }
        } else {
            if (width != 0 && height != 0) {
                intent.putExtra("aspectX", width);
                intent.putExtra("aspectY", height);
            } else {
                intent.putExtra("aspectX", 1);
                intent.putExtra("aspectY", 1);
            }
        }

        // outputX outputY 是裁剪图片宽高
//        widht / height = 500 / x;
            if(width != 0 && height != 0) {
                intent.putExtra("outputX", 500);
                intent.putExtra("outputY", 500*height/width);
            }else {
                intent.putExtra("outputX", 300);
                intent.putExtra("outputY", 300);
            }
        intent.putExtra("return-data", true);
        activity.startActivityForResult(intent, StaticInApp.ZOOM_IMAGE);
    }

然后我们会在onActivityForResult中调用

startPhotoZoom(UriUtils.pathToUri(this, selectPath), 1, 1)

从而调起图片裁剪功能。裁剪结束后,裁剪的结果会在StaticInApp.ZOOM_IMAGE标签下返回截图结果。

但是这个方法有一个问题,在华为等部分手机上,当截图的大小大于300*300时,我们的手机就会崩溃。这个让我们自己也很崩溃。这个有一个坑,就是当我们需要比较清晰的图片时,这个300*300的尺寸往往无法满足我们的需求。那么究竟是为什么会出现这种问题呢。原来在华为等手机上有一个问题,裁剪后的图片由于清晰度太高,图片太大,造成通过intent.putExtra("return-data",true);的方式无法传递。所以我们改一种方法来进行图片的裁剪传递。

我们首先定义一个全局变量private Uri imageCropUri;

然后,我们在当前类中写一个跳转截图的方法和一个删除当前图片的方法

/**
     * 华为等手机大容量裁剪防内存溢出
     *
     * @param uri
     * @param width
     * @param height
     */
    public void cropRawPhoto(Uri uri, int width, int height) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        if (android.os.Build.MODEL.contains("HUAWEI")) {
            intent.putExtra("aspectX", 9998);
            intent.putExtra("aspectY", 9999 * height / width);
        } else {
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1 * height / width);
        }
        intent.putExtra("outputX", 700);
        intent.putExtra("outputY", 700);
        String path = "file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/yulin/" + "small.jpg";
        File file = new File(path);
        delFile(file);
        imageCropUri = Uri.parse(path);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", false);
        startActivityForResult(intent, StaticInApp.ZOOM_IMAGE);
    }

    /**
     * 删除临时文件
     *
     * @return
     */
    private void delFile(File file) {
        if (file.exists()) {
            file.delete();
        }
    }

可以看到,它的原理是把图片保存在一个当前的文件目录下,然后进行下一步的操作。

同样在onActivityForResult中的StaticInApp.ZOOM_IMAGE中,我们进行以下操作

if (data != null) {
                        try {
                            bitmapCrop = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageCropUri));
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                    } else {
                        Log.e("ffl", "onActivityResult: -------------intent为null------------");
                    }

我们就可以获取到想要的图片了。

原文地址:https://www.cnblogs.com/widgetbox/p/7927623.html