当图片过大,或图片数量较多时使用BitmapFactory解码图片会出java.lang.OutOfMemoryError: bitmap size exceeds VM budget,要想正常使用则需分配更少的内存,具体的解决办法是修改采样值BitmapFactory.Options.inSampleSize,例如:
- BitmapFactory.Options opts = new BitmapFactory.Options();
-
opts.inSampleSize = 4;
- Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
如何设置恰当的inSampleSize
设置恰当的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提供了一种动态计算的方法。
- 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 lowerBound;
- }
-
-
if ((maxNumOfPixels == -1) &&
-
(minSideLength == -1)) {
-
return 1;
-
} else if (minSideLength == -1) {
-
return lowerBound;
-
} else {
-
return upperBound;
- }
- }
使用该算法,就可动态计算出图片的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) {
- }
-
另外,可以通过Bitmap.recycle()方法来释放位图所占的空间,当然前提是位图没有被使用
分享到:
相关推荐
在 Android 中,用 bitmap 时很容易内存溢出,报如下错误:Java.lang.OutOfMemoryError:bitmap size exceeds VM budget。解决这个问题可以通过手动干涉 GC 去处理 bitmap 设置图片尺寸,避免内存溢出。 例如: ```...
当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`异常,导致应用崩溃。为了解决这个问题,开发者需要采取一些策略来优化图片...
E/AndroidRuntime(12517): java.lang.OutOfMemoryError: bitmap size exceeds VM budget ``` 这段日志显示了当尝试分配1MB内存时,由于超出了24MB的限制,导致了应用崩溃。 #### 三、解决方案 针对这个问题,...
当应用尝试加载超出虚拟机内存预算的大图片时,会抛出一个常见的异常java.lang.OutOfMemoryError: bitmap size exceeds VM budget。图片加载时的内存溢出主要因为大尺寸图片占用的内存远远超过了分配给应用的内存...
当Android系统尝试分配一块超过其当前可用内存大小的内存时,会抛出`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`异常。从日志可以看出,问题出现在尝试解码一个资源(可能是图片)到Bitmap对象时,...
当尝试加载大尺寸的图片时,可能会遇到`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`错误,这是因为Android虚拟机(VM)的内存预算有限,尤其是对于较大的图片,如果直接加载原图,会消耗大量内存,...
频繁使用静态的Bitmap或Drawable可能导致`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`异常,因此应谨慎使用。 第三种方法是基于外部存储的数据传输,包括File、SharedPreferences、SQLite和...