項目中我們在進行圖片上傳時,往往不是選擇好圖片直接上傳就好,而是需要進行一些操作,比如裁剪。通常我的的裁剪是這樣的。
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------------"); }
我們就可以獲取到想要的圖片了。