关于大图片裁剪在华为等手机上无法使用问题
项目中我们在进行图片上传时,往往不是选择好图片直接上传就好,而是需要进行一些操作,比如裁剪。通常我的的裁剪是这样的。
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------------"); }
我们就可以获取到想要的图片了。