`
zhchzs
  • 浏览: 1844 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

bitmap设置图片尺寸缩小,避免内存溢出/OutOfMemoryError的优化方法

阅读更多
我们都知道Android的Dalvik VM为一个应用提供了大约16MB的内存,一般我们处理超过8MB的图片将会出现OutOfMemoryError异常(内存溢出异常),报如下错误:

20155392-byte external allocation too large for this process.

VM won't let us allocate 20155392 bytes


Java.lang.OutOfMemoryError : bitmap size exceeds VM budget   

Java代码 FileInputStream in;   in = new FileInputStream(path);   byte[] buffer = new byte[1024];   ByteArrayOutputStream out = new ByteArrayOutputStream();   int len = 0;   while ((len = in.read(buffer)) != -1) {       out.write(buffer, 0, len);   }   imageData = out.toByteArray();   Bitmap bitMap = BitmapFactory.decodeByteArray(imageData, 0,imageData.length);
以上是第一次开始写浏览图片,只看到decodeByteArray方法就直接把从SD卡获取图片路径转换为byte[]然后再赋给Bitmap,原来还有一个直接从路径获取Bitmap的方法:

Java代码 Bitmap bitMap = BitmapFactory.decodeByteArray(paht) ;


但由于需要显示的图片太大,预览图片就提示内存溢出(但找到资料说处理超过8MB的图片将会出现OutOfMemoryError异常,开始第一段话),不过我显示的图片为4M也出现



20155392-byte external allocation too large for this process.

VM won't let us allocate 20155392 bytes



可能是 20155392算出来大概19M的大少,可能超出了分配给程序的16M大少



我们解码(预览显示)一个图片为了防止内存不足的异常我们可以使用BitmapFactory.Options 的属性解决,代码如下:



1、通过路径获取图片


Java代码  ImageView imageView=(ImageView)findViewById(R.id.image);  BitmapFactory.Options options = new BitmapFactory.Options();  options.inSampleSize=2;//图片高宽度都为原来的二分之一,即图片大小为原来的大小的四分之一  options.inTempStorage = new byte[5*1024]; //设置16MB的临时存储空间(不过作用还没看出来,待验证)  Bitmap bitMap = BitmapFactory.decodeFile(文件路径, options);   imageView.setImageBitmap(bitMap); 
 



2、通过Uri取图片



Java代码  Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options);  
以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。







以下是网上找到的资料:

★Android 还有一些性能优化的方法:

●  首先内存方面,可以参考 Android堆内存也可自己定义大小 和 优化Dalvik虚拟机的堆内存分配
●  基础类型上,因为Java没有实际的指针,在敏感运算方面还是要借助NDK来完成。这点比较有意思的是Google推出NDK可能是帮助游戏开发人员,比如OpenGL ES的支持有明显的改观,本地代码操作图形界面是很必要的。
●  图形对象优化,这里要说的是Android上的Bitmap对象销毁,可以借助recycle()方法显示让GC回收一个Bitmap对象,通常对一个不用的Bitmap可以使用下面的方式,如


Java代码  if(bitmapObject.isRecycled()==false) //如果没有回收                  bitmapObject.recycle();  
●  目前系统对动画支持比较弱智对于常规应用的补间过渡效果可以,但是对于游戏而言一般的美工可能习惯了GIF方式的统一处理,目前 Android系统仅能预览GIF的第一帧,可以借助J2ME中通过线程和自己写解析器的方式来读取GIF89格式的资源。
● 对于大多数Android手机没有过多的物理按键可能我们需要想象下了做好手势识别 GestureDetector 和重力感应来实现操控。通常我们还要考虑误操作问题的降噪处理。
Android堆内存也可自己定义大小
   对于一些大型Android项目或游戏来说在算法处理上没有问题外,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了上次Android开发网提到的 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:

Java代码  private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;         VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。      private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。 


当然对于内存吃紧来说还可以通过手动干涉GC去处理,我们将在下次提到具体应用。
优化Dalvik虚拟机的堆内存分配
对于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用 dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法: 

Java代码  private final static floatTARGET_HEAP_UTILIZATION = 0.75f;        private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 
在程序onCreate时就可以调用

Java代码  VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);        VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);  
★android 系统中读取位图Bitmap时.分给虚拟机中图片的堆栈大小只有8M。所以不管是如何调用的图片,太多太大虚拟机肯定会报那个错误。超出图片内存预算那个错误.:java.lang.OutOfMemoryError: bitmap size exceeds VM budget

遇到这个问题是因为没有回收资源.

Java代码  public void distoryBitmap(){           if(null!=bmb&&!bmb.isRecycled())               bmb.recycle();      
调用上面的代码可以基本解决这个问题.但是千万不要在view中的onDraw()中调用.因为onDraw()方法是系统循环调用.只要图片打开,系统就不停的调用该方法.

最好的解决方案是在自定义的View中添加一个init()初始化方法的头部调用.或者在构造函数的顶部调用。


分享到:
评论

相关推荐

    处理bitmap内存溢出问题

    在Android开发中,处理`Bitmap`内存溢出问题是一个常见的挑战,尤其是在处理高分辨率或大尺寸图片时。当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap...

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

    2. **使用inSampleSize属性进行下采样**:在`BitmapFactory.Options`中设置`inSampleSize`属性为大于1的整数,表示对原图进行下采样处理,即按照指定的比例缩小图片尺寸,从而减少内存占用。 3. **释放不再使用的...

    完善的压缩bitmap测试工程

    在安卓开发中,Bitmap是用于处理图像数据的重要类,它占据了大量的内存,特别是在处理高清图片时,可能会引发内存溢出(OutOfMemoryError)问题。因此,对Bitmap进行压缩是优化应用性能的关键环节。这个“完善的压缩...

    Android加载图片内存溢出问题解决方法

    当`inPurgeable`为False时,`inInputShareable`的设置无效,但若`inPurgeable`为True,`inInputShareable`设置为True可以让系统在内存不足时尝试通过文件系统共享内存,进一步优化内存使用。 最后,推荐使用`...

    android Bitmap用法总结

    Bitmap是Android平台中用于处理图像的核心类,它用于表示位图图像数据。...在处理大量图片时,注意优化内存使用,避免OutOfMemoryError。合理运用上述方法可以有效地管理Bitmap资源,提高应用性能。

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

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

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

    1. 图片尺寸:Bitmap的宽度和高度直接影响内存占用。每个像素通常占用4字节(ARGB_8888格式),因此宽度乘以高度就是基本的内存占用。 2. 图片格式:不同的颜色模式(如RGB_565、ARGB_4444等)占用的内存不同,ARGB_...

    android中大图缩小

    "android中大图缩小"这个话题聚焦于如何优化大尺寸图片的处理,以避免内存溢出(OutOfMemoryError)等问题。以下是关于Android中大图缩小的一些关键知识点: 1. **Bitmap对象与内存管理**: - Android中的`Bitmap`...

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

    - **使用BitmapFactory.Options**:通过设置`inSampleSize`参数,缩小图片的解码尺寸,减少内存消耗。 - **使用LruCache或其他缓存机制**:缓存缩略图或处理过的图片,避免重复加载和解码。 - **及时回收Bitmap**...

    android大位图二次采样处理三

    2. 计算采样率:理想的inSampleSize应该是2的幂,如2, 4, 8等,这样可以保证解码后的图片尺寸为整数倍缩放,避免失真。 三、高效的二次采样处理 1. 预计算尺寸:在加载位图前,根据目标视图的大小计算合适的...

    仿微信图片上传,带有拍照,并可以放大缩小预览

    可以使用`BitmapFactory.Options`的`inSampleSize`参数减小图片尺寸,或者使用`Bitmap.createScaledBitmap()`来缩放图片。此外,使用`LruCache`或` Glide's Memory Cache`进行缓存管理也是防止内存泄漏的有效手段。 ...

    Android图片质量压缩

    为了避免这种情况,可以使用上述的`inSampleSize`来预加载缩放后的图片,或者使用`Bitmap.createScaledBitmap()`来动态调整Bitmap的尺寸。 4. **使用第三方库**: 对于更复杂的图片压缩需求,可以考虑使用第三方库...

    关于Android bitmap你不知道的一些事

    最后,再次使用Options对象,设置`inSampleSize`为计算的缩放比例,解码图片,此时Bitmap将按比例缩小,降低内存需求。 除了加载和缩放,有时还需要对Bitmap进行修改,例如调整颜色、添加滤镜或裁剪。这通常涉及...

    Android 点击查看大图

    1. **图片加载库**:在Android中,由于原生Bitmap对象的内存管理问题,直接加载大图可能导致内存溢出(OutOfMemoryError)。因此,开发者通常会选择使用第三方图片加载库,如Glide、Picasso或Fresco。这些库能够自动...

    Android加载大分辨率图片到手机内存中的实例方法

    当尝试加载大尺寸图片时,如果直接使用BitmapFactory.decodeFile()方法,图片的完整像素会被加载到内存中,占用大量空间,从而可能引发`java.lang.OutOfMemoryError`。 为了理解这个问题,让我们分析一个实际的案例...

    笔记分享---Android 高清加载巨图

    例如,如果原图是2048x2048像素,设置inSampleSize为4,则加载的图片尺寸会变为512x512。 三、加载策略 1. **懒加载**(Lazy Loading):只在需要显示图片时才开始加载,减少不必要的资源消耗。 2. **分块加载**...

    Android如何高效显示较大的Bitmaps

    在Android开发中,高效地处理和显示大尺寸的Bitmaps是非常关键的,因为不恰当的处理方式可能导致内存溢出(OutOfMemoryError),严重影响应用的性能和用户体验。以下是一些关于如何高效显示大Bitmaps的详细步骤和...

    Android 按指定大小读取图片的实例

    本文将详细讨论如何按照指定大小来读取图片,避免图片过大导致内存溢出(OutOfMemoryError)或图片过小影响用户体验的问题。我们将通过一个实例来讲解如何实现这一功能。 首先,我们需要获取图片文件的实际宽度和...

    Android图片采样缩放功能实例代码

    理想情况下,inSampleSize应该是2的幂,如2、4、8等,因为这样可以确保图片尺寸以2的倍数递减,从而达到更好的内存管理效果。然而,不是所有Android版本都要求inSampleSize必须是2的幂,某些情况下系统会自动调整为...

Global site tag (gtag.js) - Google Analytics