从上篇文章中我们知道裁剪之后得到的是bitmap,这时候我们直接用图片加载控件使用setImageBitmap加载bitmap就行了。然而现在我不想剪切了,就在相册中直接选取加载怎么办,我们调用相册或摄像头拍照获取到的结果是一个本地图片的uri,我们怎么加载这一个uri呢?
方式一:
直接使用imageView.setImageURI(uri);
但是这种方式不稳定,经常会报错,所以一般不用。
方式二:
把uri变成bitmap加载
Bitmap 和 uri 互变方法:
1、bitmap to uri
Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null,null));
2、uri to bitmap
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
会出现的问题:
使用MediaStore.Images.Media.getBitmap把uri变成bitmap,加载多张图片会造成的OOM异常
原因:
getBitmap是一个简单粗暴的方法,我们没有要得到的bitmap的大小,所以返回的bitmap的大小我们不知道多少,完全由要加载的本地图片的大小决定,而现在的本地拍摄的图片比较大,所以加载四五张之后就可能会造成OOM溢出,所以我们要对bitmap展示前进行压缩。
getBitmap的源码:
public static final Bitmap getBitmap(ContentResolver cr, Uri url)
throws FileNotFoundException, IOException {
InputStream input = cr.openInputStream(url);
Bitmap bitmap = BitmapFactory.decodeStream(input);
input.close();
return bitmap;
}
压缩方法:
public String getPath(Uri uri)
{
String[] projection = {MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
public final static Bitmap lessenUriImage(String path){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, options); //此时返回 bm 为空
options.inJustDecodeBounds = false; //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = (int)(options.outHeight / (float)320);
if (be <= 0)
be = 1;
options.inSampleSize = be; //重新读入图片,注意此时已经把 options.inJustDecodeBounds 设回 false 了
bitmap=BitmapFactory.decodeFile(path,options);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
System.out.println(w+" "+h); //after zoom
return bitmap;
}
这样,我们就能流畅的加载本地图片了。
版权所有,转载请注明出处!