Android内存溢出BitmapFactory decoding大文件
来源:互联网 发布:2016我国旅游业数据 编辑:程序博客网 时间:2024/06/09 13:56
在android设备上(where you have only 16MB memory available),如果使用Bitmap
先说之前提到过的一种方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价。在BitmapFactory中有一个内部类BitmapFactory.Options,其中当options.inSampleSize值>1时,根据文档:
If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. (1 -> decodes full size; 2 -> decodes 1/4th size; 4 -> decode 1/16th size). Because you rarely need to show and have full size bitmap images on your phone. For manipulations smaller sizes are usually enough.
也就是说,options.inSampleSize是以2的指数的倒数被进行放缩。这样,我们可以依靠inSampleSize的值的设定将图片放缩载入,这样一般情况也就不会出现上述的OOM问题了。现在问题是怎么确定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提供了一种动态计算的方法。如下:
public Bitmap getBitmapFromFile(File dst, int width, int height) { if (null != dst && dst.exists()) { BitmapFactory.Options opts = null; if (width > 0 && height > 0) { opts = new BitmapFactory.Options();<br><br> //设置inJustDecodeBounds为true后,decodeFile并不分配空间,此时计算原始图片的长度和宽度 opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(dst.getPath(), opts); // 计算图片缩放比例 final int minSideLength = Math.min(width, height); opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height);<br><br> //这里一定要将其设置回false,因为之前我们将其设置成了true opts.inJustDecodeBounds = false; opts.inInputShareable = true; opts.inPurgeable = true; } try { return BitmapFactory.decodeFile(dst.getPath(), opts); } catch (OutOfMemoryError e) { e.printStackTrace(); } } 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; }}
这样,在BitmapFactory.decodeFile执行处,也就不会报出上面的OOM Error。
如前面提到的,这种方式在一定程度上是以牺牲图片质量为代价的。如何才能更加优化的实现需求?
当在android设备中载入较大图片资源时,可以创建一些临时空间,将载入的资源载入到临时空间中。
BitmapFactory.Options bfOptions=new BitmapFactory.Options();bfOptions.inTempStorage=newbyte[12 * 1024];
以上创建了一个12kb的临时空间。然后使用
Bitmap bitmapImage = BitmapFactory.decodeFile(path,bfOptions);
但是我在程序中却还是出现以上问题!以下使用BitmapFactory.decodeFileDescriptor解决了以上问题:
BitmapFactory.Options bfOptions=new BitmapFactory.Options(); bfOptions.inDither=false; bfOptions.inPurgeable=true; bfOptions.inTempStorage=newbyte[12 * 1024]; bfOptions.inJustDecodeBounds = true; File file = new File(pePicFile.getAbsolutePath() + "/"+info.getImage()); FileInputStream fs=null; Bitmap bmp = null; try { fs = new FileInputStream(file); if(fs != null) bmp = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions); } catch (Exception e) { e.printStackTrace(); } 当然要将取得图片进行放缩显示等处理也可以在以上得到的bmp进行。图片处理后记得回收内存if(!bmp.isRecycle() ){ bmp.recycle() //回收图片所占的内存 system.gc() //提醒系统及时回收}
- Android内存溢出BitmapFactory decoding大文件
- Android内存溢出BitmapFactory decoding大文件
- Android内存溢出BitmapFactory decoding大文件
- Android内存溢出解决办法BitmapFactory decoding大文件
- Android:BitmapFactory decoding大文件中产生OutOfMemoryError解决规划
- android BitmapFactory的内存溢出
- BitmapFactory decoding大文件中产生OutOfMemoryError解决方案
- Android加载图片内存溢出BitmapFactory.Options
- Android(decode文件转成bitmap)使用BitmapFactory.Options解决加载大图片内存溢出
- BitmapFactory.Options解决Android加载图片内存溢出的问题
- ByteArrayOutputStream 大文件内存溢出
- Android 内存溢出大总结
- BitmapFactory.decodeFile图片过大内存溢出
- BitmapFactory.decodeFile内存溢出和变相解决方案
- BitmapFactory.decodeStream 内存溢出java.lang.OutOfMemoryError
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- application/x-www-form-urlencoded
- Linux芯片级移植与底层驱动(基于3.7.4内核) --中断控制器
- 源磊科技顺应并购潮流,再续创富辉煌
- Linux芯片级移植与底层驱动(基于3.7.4内核) --内核节拍
- linux shell 实现后台多进程运行的,开始和终止
- Android内存溢出BitmapFactory decoding大文件
- 数据库设计的几个原则
- 14个支持响应式设计的流行前端开发框架
- python对流进行join
- 滚动条到底部时自己加载新的内容
- 技术负责人的三种角色
- 图
- Linux RT(2)-硬实时Linux(RT-Preempt Patch)的中断线程化
- 计算机如何启动(How Computers Boot Up)