`
cb269267
  • 浏览: 25262 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(转)解决 bitmap size exceeds VM budget (Out Of Memory 内存溢出)的问题

 
阅读更多
在做图片处理的时候最常遇到的问题估计就是Out Of Memory (内存溢出)了
网上对这种问题的解决方案很多,原来无非就是压缩图片大小
本不该重复造轮子,但实际中却遇见了问题,写出来希望后来者能引以为戒,并给出一个自我感觉不错的方案

常用的一种解决方案:

FileInputStream f = new FileInputStream(file);
BitmapFactory.Options options = new BitmapFactory.Options();  
options.inSampleSize = 2;//将图片大小改为原来的1/4
Bitmap bm = BitmapFactory.decodeStream(f, null, options);


其中options.inSampleSize定义如下:
If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder will try to fulfill this request, but the resulting bitmap may have different dimensions that precisely what has been requested. Also, powers of 2 are often faster/easier for the decoder to honor.
也就是说options.inSampleSize = 2就是将原图片的高和宽都设为1/2(单位为像素),整体图片也就缩小成原来的1/4之一了
这当然是一种很好的解决方案,只需根据自己的需要设置缩放比就行。

但这仅仅解决了一部分问题
试想一下,如果每张图片的大小都不一样,而要显示在相同的控件中,这时的缩放比(options.inSampleSize)该设置成多少呢?
如果设置缩放基本不够小,对于大像素图片的处理依然会出现内存溢出,设置得太大又会导致图片失真
这真是个头疼的问题。
如果能够根据图片大小自动计算缩放比那该多好啊!

别急,google已经为我们提供了这么一个方法(出自源码 暂且保存为BitmapUtiles.java 方便以后使用):

public class BitmapUtils
{
 
public static int computeSampleSize(BitmapFactory.Options options,
         int minSideLength, int maxNumOfPixels) {
     int initialSize = computeInitialSampleSize(options, minSideLength,
             maxNumOfPixels);
 
     int roundedSize;
     if (initialSize <= {
         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;
     }
}
}

我们只需要这样使用就好了:



FileInputStream f = new FileInputStream(file);
FileDescriptor fd = f.getFD();
  
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
options.inSampleSize = BitmapUtils.computeSampleSize(options, 80, 128*128);
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeStream(f, null, options);



其中需要注意的是options.inJustDecodeBounds这个属性,API解释如下:
If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
在设置为true的情况下不会返回bitmap,即不会占用内存,但可以计算bitmap的size大小(BitmapFactory.decodeFileDescriptor(fd, null, options) 由options带回宽、高)
此时的操作就是为了得到高、宽用于后面缩放比的计算
BitmapUtils.computeSampleSize(options, 80, 128*128)中
80是最小边长,128*128是期望得到的图像像素

特别注意的是,计算完宽高后一定要将改属性设置为false,否则BitmapFactory.decodeStream会一直返回null

OK,讲得够详细了

转自:http://blog.csdn.net/lovehong0306/article/details/7741436#comments
分享到:
评论

相关推荐

    处理bitmap内存溢出问题

    当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`异常,导致应用崩溃。为了解决这个问题,开发者需要采取一些策略来优化图片...

    ANDROIDBITMAP内存限制OOM,OUTOFMEMORY[文].pdf

    在Android开发中,我们经常会遇到内存管理的问题,特别是与Bitmap相关的内存溢出(Out Of Memory,简称OOM)问题。Bitmap对象是Android系统中用于处理图像数据的重要类,但由于其消耗大量的内存,不当使用可能导致...

    ANDROIDBITMAP内存限制OOM,OUTOFMEMORY.pdf

    文档标题和描述中提到的“ANDROIDBITMAP内存限制OOM,OUTOFMEMORY”指的就是在处理位图(BITMAP)时超出了虚拟机(VM)的内存预算,导致系统抛出OutOfMemoryError异常。 根据给出的内容部分,我们可以推断出以下知识...

    android_内存溢出处理

    在 Android 中,用 bitmap 时很容易内存溢出,报如下错误:Java.lang.OutOfMemoryError:bitmap size exceeds VM budget。解决这个问题可以通过手动干涉 GC 去处理 bitmap 设置图片尺寸,避免内存溢出。 例如: ```...

    bitmap内存问题

    内存溢出(Out Of Memory,简称OOM)通常发生在应用消耗的物理内存超过了系统分配给它的最大内存限制。对于Android而言,当一个进程使用的本机或Java堆内存超过了一定阈值时,就会触发OOM错误。`Bitmap`作为占用内存...

    android bitmap outOfMemory解决方法

    本文将深入探讨Android Bitmap导致的`OutOfMemoryError`问题,以及如何有效地解决这个问题。 首先,我们需要了解`OutOfMemoryError`是如何产生的。在Java(包括Android)中,每个应用都有一定的内存限制。当应用...

    图片过大引起的内存溢出解决方案

    ### 图片过大引起的内存溢出解决方案 在Android开发过程中,我们经常会遇到因加载大尺寸图片而引发的`OutOfMemoryError`(内存溢出错误)。这种问题通常发生在使用`BitmapFactory`来加载图片时,尤其是在资源有限的...

    Android 内存溢出问题

    然而,如果应用程序在短时间内分配大量内存,或者持有大量无法释放的对象引用,就可能导致内存溢出(Out Of Memory,OOM)。 例如,错误信息"02-04 21:46:08.703: ERROR/dalvikvm-heap(2429): 1920000-byte ...

    android 处理图片内存溢出 VM.pdf

    可能会遇到`java.lang.OutOfMemoryError: bitmap size exceeds VM budget`错误,这是因为Android虚拟机(VM)的内存预算有限,尤其是对于较大的图片,如果直接加载原图,会消耗大量内存,从而导致内存溢出。...

    android 图片下载 有效解决内存溢出问题

    在Android开发中,图片下载和显示是常见的操作,但如果不恰当处理,很容易引发内存溢出(Out of Memory,简称OOM)问题。内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,导致程序崩溃。对于Android应用...

    android处理图片内存溢出VM.pdf

    当应用尝试加载超出虚拟机内存预算的大图片时,会抛出一个常见的异常java.lang.OutOfMemoryError: bitmap size exceeds VM budget。图片加载时的内存溢出主要因为大尺寸图片占用的内存远远超过了分配给应用的内存...

    android双缓冲解决图片内存溢出的问题

    在Android开发中,处理大量的图片资源时,常常会遇到内存溢出(Out Of Memory,简称OOM)的问题。这是因为Android系统为每个应用分配的内存有限,当加载过多或过大的图片时,很容易超出这个限制,导致应用崩溃。为了...

    加载大图片的时候如何防止内存溢出

    在 Android 系统中,加载大图片时经常会出现内存溢出的问题,这是因为 Android 系统给图片分配的内存只有 8M,当加载大量图片时,很容易超出这个限制,导致 OOM(Out of Memory)错误。为了解决这个问题,我们需要...

    Android有效解决加载大图片时内存溢出的问题

    因此,解决加载大图片时的内存溢出问题是非常重要的。 一、使用 BitmapFactory.Options 在加载大图片时,可以使用 BitmapFactory.Options 来减少内存的消耗。BitmapFactory.Options 提供了一些选项来调整图片的...

    android 显示大的gif图片 能解决内存溢出的问题

    在Android平台上,显示大型GIF图像可能会导致内存溢出(Memory Overflow)问题,因为GIF是一种动画格式,它包含多帧连续的图像,如果直接加载到内存中,会占用大量资源。为了解决这个问题,我们可以采用一些技术策略...

    android 轻松避免内存溢出

    在Android开发中,内存管理是至关重要的,尤其是处理图片资源时,经常遇到内存溢出(Out Of Memory,简称OOM)的问题。本项目提供了一个在Android 1.6 SDK环境下编写的工具类,旨在帮助开发者有效地避免内存溢出,...

    android解决加载图片内存溢出

    在Android开发中,图片加载是常见且关键的操作,但如果不恰当处理,很容易导致内存溢出(Out of Memory,简称OOM)问题。内存溢出不仅会影响应用的性能,降低用户体验,严重时甚至会导致应用崩溃。本篇文章将深入...

    Android避免内存溢出(Out of Memory)方法汇总

    在Android开发中,内存管理是至关重要的,尤其是避免内存溢出(Out of Memory,简称OOM)。内存溢出会导致应用程序崩溃,影响用户体验。本篇文章将详细阐述如何在Android中有效地防止内存溢出,主要包括理解不同类型...

    Android 内存溢出的一些解决办法.doc

    在Android开发中,内存溢出(Out Of Memory,简称OOM)是一个常见的问题,尤其是在处理大量图像资源时。本文将详细探讨几种解决Android内存溢出的方法。 首先,针对图像导致的内存溢出,一种常见的解决方案是使用`...

Global site tag (gtag.js) - Google Analytics