从手机中获取图片遇到的OOM问题解析
在安卓开发过程中,一个无可避免的功能就是通过图库或者拍照来获取图片。
在这个过程中,一个最经典的错误就是由于图片过大而造成的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;
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。