在安卓開發過程中,一個無可避免的功能就是通過圖庫或者拍照來獲取圖片。
在這個過程中,一個最經典的錯誤就是由於圖片過大而造成的OOM問題。
首先調用圖庫或者是拍照功能
/**
* 圖庫選擇
*/
public static void choicephoto(Activity activity) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Intent intent = new Intent();
intent.setType(IMAGE_UNSPECIFIED);
intent.setAction(Intent.ACTION_GET_CONTENT);
activity.startActivityForResult(intent, CHOICEPHOTO);
} else {
Toast.makeText(activity, "請先插入SD卡", Toast.LENGTH_LONG).show();
}
}
/**
* 拍照
*/
public static void takephoto(Activity activity) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(intent, TAKEPHOTO);
} else {
Toast.makeText(activity, "請先插入SD卡", Toast.LENGTH_LONG).show();
}
}
- 上面兩個方法使用的Activity類型作爲參數,如果是在Fragment啓用該功能的話,參數處應傳遞Fragment類型
- CHOICEPHOTO和TAKEPHOTO和兩個int類型常量,可自行定義他們的數值。
當選擇圖片完成後,通過onActivityResult方法得到返回的數據
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode != RESULT_OK || data == null) {
return;
}
switch (requestCode) {
case CHOICEPHOTO:
//從圖庫選擇的圖片根據手機不同,會有兩種返回數據方式
Uri uri = data.getData();
if (uri != null) {
//OOM問題主要出現在此處,需對Bitmap進行壓縮處理後再返回
photo = ImageUtils.compressImage(this, uri);
//對圖片進行展示或者其他操作
showImg();
} else {
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
showImg();
}
}
break;
case TAKEPHOTO:
photo = data.getExtras().getParcelable("data");
showImg();
break;
}
}
- 如果此處發生OOM,往往是由於Bitmap的分辨率過大造成的,因此需要對圖片分辨率進行壓縮處理後,再次展示
ImageUtils.compressImage(this, uri);方法的代碼如下
public static Bitmap compressImage(Context context, Uri uri) {
//壓縮參考尺寸(PX)
float hh = 1280f;
float ww = 720f;
//圖片寬高
BitmapFactory.Options options = new BitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設爲true
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
//根據uri得到圖片的具體地址
String path = FileUtils.getImageAbsolutePath(context, uri);
//此時返回bm爲空
BitmapFactory.decodeFile(path, options);
//得到圖片的寬高
float w = options.outWidth;
float h = options.outHeight;
//壓縮倍率
float be = 1.0f;
if (w > h) {
be = ((w / hh + h / ww) / 2.0f);
} else {
be = ((w / ww + h / hh) / 2.0f);
}
//個人邏輯,僅供參考
if (be <= 1.5f) {
be = 1;
}
options.inSampleSize = (int) be;//設置縮放比例
options.inJustDecodeBounds = false;
//得到處理後的bitmap並返回
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
return bitmap;
}
}