原出处:http://2711082222.blog.163.com/blog/static/10630224920123635918767/
这一个没测试,想来必定能运行。分享和自己学习。
当图片过大,或数量较多时使用BitmapFactory解码图片会出java.lang.OutOfMemoryError: bitmap size exceeds VM budget
android系统中读取位图Bitmap时.分给虚拟机中图片的堆栈大小只有8M。所以不管是如何调用的图片,太多太大虚拟机肯定会报那个错误。
遇到这个问题是因为没有回收资源.
public void distoryBitmap(){
if(null!=bmb&&!bmb.isRecycled())
bmb.recycle();
}
public class GifView extends View implements Runnable {
private Bitmap bmb;
public GifView(Context context, InputStream inputStream) {
super(context);
distoryBitmap();
bmb = BitmapFactory.decodeStream(is);
}
}
调用上面的代码可以基本解决这个问题.但是千万不要在view中的onDraw()中调用.因为onDraw()方法是系统循环调用.只要图片打开.
系统就不停的调用该方法.
最好的解决方案是在自定义的View中添加一个init()初始化方法的头部调用.或者在构造函数的顶部调用:
来自:http://www.apkbus.com/android-1179-1-1.html
当图片过大,或数量较多时使用BitmapFactory解码图片会出java.lang.OutOfMemoryError: bitmap size exceeds VM budget.
一般取缩略图的方法是使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
要想正常使用则需分配更少的内存,具体的解决办法是修改采样值BitmapFactory.Options.inSampleSize。
修改采样值BitmapFactory.Options.inSampleSize,例如:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
设置恰当的inSampleSize是解决该问题的关键之一。BitmapFactory.Options提供了另一个成员inJustDecodeBounds。
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
查看Android源码,Android提供了一种动态计算的方法,方法如下面例子
private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels)
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels)
使用该算法,就可动态计算出图片的inSampleSize。
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageFile, opts);
opts.inSampleSize = computeSampleSize(opts, -1, 128*128);
opts.inJustDecodeBounds = false;
try {
Bitmap bmp = BitmapFactory.decodeFile(imageFile, opts);
imageView.setImageBitmap(bmp);
} catch (OutOfMemoryError err) {
}
来自:http://blog.youkuaiyun.com/yangxyjd/article/details/6932989
我的应用 eg.
public static final Bitmap getFitBitmap(String path)
{
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true ;
BitmapFactory.decodeFile(path, opts);
opts.inSampleSize = computeSampleSize(opts, - 1 , 1200*800 );
Log.e("bili", opts.inSampleSize+"");
opts.inJustDecodeBounds = false ;
try {
Bitmap bmp = BitmapFactory.decodeFile(path, opts);
return bmp;
} catch (OutOfMemoryError err) {
}
return null;
}
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels);
int roundedSize;
if (initialSize <= 8 ) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}
private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 :
(int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 :
(int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) &&
(minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
/**
* change uri to path string
* @param uri
* @return
*/
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);
}
调用:
protected void onActivityResult(int requestCode, int resultCode, Intent data) 中
Uri uri1 = data.getData();
String selectedImagePath1 = getPath(uri1);
//..........
//firstPhoto.setImageURI(uri1);
//firstPhoto.setImageBitmap(BaseMean.lessenUriImage(selectedImagePath1));
btOne =RevoPubAccess.getFitBitmap(selectedImagePath1);
红色处要是添加这句,
Log.e(TAG, uri1+";;;;"+selectedImagePath1+",,,,"+uri1.getPath());
结果如下:
content://media/external/images/media/149;;;;/mnt/sdcard/DCIM/100MEDIA/IMAG0238.jpg,,,,/external/images/media/149
本文讨论了在Android应用中使用Bitmap时遇到的内存溢出问题,并提供了通过合理设置inSampleSize解决该问题的方法。包括使用BitmapFactory.decodeFile方法获取缩略图,以及动态计算inSampleSize以优化内存使用。
1265

被折叠的 条评论
为什么被折叠?



