android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
2011-08-24 13:12
381 查看
转自:/article/5641917.html
使用android提供的BitmapFactory解码一张图片时,有时会遇到该错误,即:java.lang.OutOfMemoryError:bitmapsizeexceedsVMbudget。这往往是由于图片过大造成的。要想正常使用,一种方式是分配更少的内存空间来存储,即在载入图片的时候以牺牲图片质量为代价,将图片进行放缩,这也是不少人现在为避免以上的OOM所采用的解决方法。但是,这种方法是得不偿失的,当我们使用图片作为缩略图查看时候倒是没有说什么,但是,当需要提供图片质量的时候,该怎么办呢?java.lang.OutOfMemoryError:
bitmapsizeexceedsVMbudget着实让不少人欲哭无泪呀!前几天刚好有个需求需要载入SD卡上面的图片。
首先是使用
viewsourceprint?
上面参数是我将要读取的图片文件及路径,当文件较小时,程序能够正常运行,但是当我选择一张大图时,程序立刻蹦出了java.lang.OutOfMemoryError:bitmapsizeexceedsVMbudget的OOM错误!
在android设备上(whereyouhaveonly16MBmemoryavailable),如果使用BitmapFactory解码一个较大文件,很大的情况下会出现上述情况。那么,怎么解决?!
先说之前提到过的一种方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价。在BitmapFactory中有一个内部类BitmapFactory.Options,其中当options.inSampleSize值>1时,根据文档:
Ifsettoavalue>1,requeststhedecodertosubsampletheoriginalimage,returningasmallerimagetosavememory.(1->decodesfullsize;2->decodes1/4thsize;4->decode1/16thsize).Becauseyourarelyneedtoshowandhavefullsizebitmapimagesonyourphone.Formanipulationssmallersizesareusuallyenough.
也就是说,options.inSampleSize是以2的指数的倒数被进行放缩。这样,我们可以依靠inSampleSize的值的设定将图片放缩载入,这样一般情况也就不会出现上述的OOM问题了。现在问题是怎么确定inSampleSize的值?每张图片的放缩大小的比例应该是不一样的!这样的话就要运行时动态确定。在BitmapFactory.Options中提供了另一个成员inJustDecodeBounds。
viewsourceprint?
设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。Android提供了一种动态计算的方法。如下:
viewsourceprint?
以上参考一下,我们只需要使用此函数就行了:
viewsourceprint?
这样,在BitmapFactory.decodeFile执行处,也就不会报出上面的OOMError了。完美解决?如前面提到的,这种方式在一定程度上是以牺牲图片质量为代价的。如何才能更加优化的实现需求?
当在android设备中载入较大图片资源时,可以创建一些临时空间,将载入的资源载入到临时空间中。
viewsourceprint?
以上创建了一个12kb的临时空间。然后使用BitmapbitmapImage=BitmapFactory.decodeFile(path,bfOptions);但是我在程序中却还是出现以上问题!以下使用BitmapFactory.decodeFileDescriptor解决了以上问题:
viewsourceprint?
当然要将取得图片进行放缩显示等处理也可以在以上得到的bmp进行。
PS:请图片处理后进行内存回收。bmp.recycle();这样将图片占有的内存资源释放。
使用android提供的BitmapFactory解码一张图片时,有时会遇到该错误,即:java.lang.OutOfMemoryError:bitmapsizeexceedsVMbudget。这往往是由于图片过大造成的。要想正常使用,一种方式是分配更少的内存空间来存储,即在载入图片的时候以牺牲图片质量为代价,将图片进行放缩,这也是不少人现在为避免以上的OOM所采用的解决方法。但是,这种方法是得不偿失的,当我们使用图片作为缩略图查看时候倒是没有说什么,但是,当需要提供图片质量的时候,该怎么办呢?java.lang.OutOfMemoryError:
bitmapsizeexceedsVMbudget着实让不少人欲哭无泪呀!前几天刚好有个需求需要载入SD卡上面的图片。
首先是使用
Bitmapbmp=BitmapFactory.decodeFile(pePicFile.getAbsolutePath()+ "/" +info.getImage()); |
在android设备上(whereyouhaveonly16MBmemoryavailable),如果使用BitmapFactory解码一个较大文件,很大的情况下会出现上述情况。那么,怎么解决?!
先说之前提到过的一种方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价。在BitmapFactory中有一个内部类BitmapFactory.Options,其中当options.inSampleSize值>1时,根据文档:
Ifsettoavalue>1,requeststhedecodertosubsampletheoriginalimage,returningasmallerimagetosavememory.(1->decodesfullsize;2->decodes1/4thsize;4->decode1/16thsize).Becauseyourarelyneedtoshowandhavefullsizebitmapimagesonyourphone.Formanipulationssmallersizesareusuallyenough.
也就是说,options.inSampleSize是以2的指数的倒数被进行放缩。这样,我们可以依靠inSampleSize的值的设定将图片放缩载入,这样一般情况也就不会出现上述的OOM问题了。现在问题是怎么确定inSampleSize的值?每张图片的放缩大小的比例应该是不一样的!这样的话就要运行时动态确定。在BitmapFactory.Options中提供了另一个成员inJustDecodeBounds。
1 | BitmapFactory.Optionsopts= new BitmapFactory.Options(); |
2 | opts.inJustDecodeBounds= true ; |
3 | Bitmapbitmap=BitmapFactory.decodeFile(imageFile,opts); |
01 | public static int computeSampleSize(BitmapFactory.Optionsoptions, |
02 | int minSideLength, int maxNumOfPixels){ |
03 | int initialSize=computeInitialSampleSize(options,minSideLength, |
04 | maxNumOfPixels); |
05 |
06 | int roundedSize; |
07 | if (initialSize<= 8 ){ |
08 | roundedSize= 1 ; |
09 | while (roundedSize<initialSize){ |
10 | roundedSize<<= 1 ; |
11 | } |
12 | } else { |
13 | roundedSize=(initialSize+ 7 )/ 8 * 8 ; |
14 | } |
15 |
16 | return roundedSize; |
17 | } |
18 |
19 | private static int computeInitialSampleSize(BitmapFactory.Optionsoptions, |
20 | int minSideLength, int maxNumOfPixels){ |
21 | double w=options.outWidth; |
22 | double h=options.outHeight; |
23 |
24 | int lowerBound=(maxNumOfPixels==- 1 )? 1 : |
25 | ( int )Math.ceil(Math.sqrt(w*h/maxNumOfPixels)); |
26 | int upperBound=(minSideLength==- 1 )? 128 : |
27 | ( int )Math.min(Math.floor(w/minSideLength), |
28 | Math.floor(h/minSideLength)); |
29 |
30 | if (upperBound<lowerBound){ |
31 | return lowerBound; |
32 | } |
33 |
34 | if ((maxNumOfPixels==- 1 )&& |
35 | (minSideLength==- 1 )){ |
36 | return 1 ; |
37 | } else if
1 ){ |
38 | return lowerBound; |
39 | } else { |
40 | return upperBound; |
41 | } |
42 | } |
BitmapFactory.Optionsopts= new BitmapFactory.Options(); |
opts.inJustDecodeBounds= true ; |
BitmapFactory.decodeFile(imageFile,opts); |
opts.inSampleSize=computeSampleSize(opts,- 1 , 128 * 128 ); |
//这里一定要将其设置回false,因为之前我们将其设置成了true |
opts.inJustDecodeBounds= false ; |
try
|
Bitmapbmp=BitmapFactory.decodeFile(imageFile,opts); |
imageView.setImageBitmap(bmp); |
} catch (OutOfMemoryErrorerr){ |
} |
当在android设备中载入较大图片资源时,可以创建一些临时空间,将载入的资源载入到临时空间中。
1 | BitmapFactory.OptionsbfOptions= new BitmapFactory.Options(); |
2 | bfOptions.inTempStorage= new byte [ 12 * 1024 ]; |
01 | BitmapFactory.OptionsbfOptions= new BitmapFactory.Options(); |
02 | bfOptions.inDither= false ; |
03 | bfOptions.inPurgeable= true ; |
04 | bfOptions.inTempStorage= new byte [ 12 * 1024 ]; |
05 | //bfOptions.inJustDecodeBounds=true; |
06 | Filefile= new File(pePicFile.getAbsolutePath()+ "/" +info.getImage()); |
07 | FileInputStreamfs= null ; |
08 | try { |
09 | fs= new FileInputStream(file); |
10 | } catch (FileNotFoundExceptione){ |
11 | e.printStackTrace(); |
12 | } |
13 | Bitmapbmp= null ; |
14 | if (fs!= null ) |
15 | try { |
16 | bmp=BitmapFactory.decodeFileDescriptor(fs.getFD(), null ,bfOptions); |
17 | } catch (IOExceptione){ |
18 | e.printStackTrace(); |
19 | } finally { |
20 | if (fs!= null ){ |
21 | try { |
22 | fs.close(); |
23 | } catch (IOExceptione){ |
24 | e.printStackTrace(); |
25 | } |
26 | } |
27 | } |
PS:请图片处理后进行内存回收。bmp.recycle();这样将图片占有的内存资源释放。
相关文章推荐
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决..
- Android BitmapFactory.decodeStream方法OutOfMemoryError 解决方法
- Android BitmapFactory的OutOfMemoryError问题,最近看到
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- Android:BitmapFactory decoding大文件中产生OutOfMemoryError解决规划
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap ...
- android BitmapFactory的OutOfMemoryError 解决
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap size exceeds VM budget解决方案
- android BitmapFactory的OutOfMemoryError: bitmap ...
- BitmapFactory.decodeStream 内存溢出java.lang.OutOfMemoryError
- android java.lang.OutOfMemoryError: bitmap size exceeds VM budget
- 【android】解决因为图片太大引起的内存不足问题,Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget