当在android应用中加载一张高分辨率的图片时,十分容易出现Out of memory(OOM),这是由于内存溢出造成的,每个应用所使用的堆内存大小一般是固定的,有的是16M,有的可能会大些。那为什么这么大内存加载一张图片会溢出呢?原因就是android在加载图片的时候是使用位图来放到内存中的,那位图在内存中的占用空间计算就是 分辨率*每个像素占用的内存(
ALPHA_8:每个像素占用1byte内存
ARGB_4444:每个像素占用2byte内存
ARGB_8888:每个像素占用4byte内存
RGB_565:每个像素占用2byte内存),
举个例子,如果一个图片的分辨率是1024*768,采用ARGB_8888,那么占用的空间就是1024*768*4=3MB,这张图片需要占用3M的内存空间,对于这样的图片,如果只加载一样的话,内存还能应付的过来,如果分辨率更高呢,特别是相机的照片,例如:3648*2736的一样照片,内存占用为3648*2736*4=33MB,这一张图片就是占用33MB的空间,肯定会导致内存溢出。那应该如何处理呢?
第一,降低图片加载到内存时的图片大小(分辨率)。
第二,采用更节省内存的编码,例如ARGB_4444。
第三,如果是加载大量图片的话,还可以采用缓存(这里不讨论)。
我们主要说第一和第二如何实现。
-
降低图片大小,由于移动设备的屏幕尺寸有限,即使将高分辨率图片的分辨率降低,也不会影响显示效果。那如何降低呢?就需要用到一个类,那就是BitmapFactory.options类,主要会用到这个类的inSampleSize、inJustDecodeBounds、outHeight、outWidth参数。
inSampleSize:缩放比例,这个参数需要是2的幂函数。
inJustDecodeBounds:如果设置这个参数为ture,就不会给图片分配内存空间,但是可以获取到图片的大小等属性。
outHeight:图片高,单位像素.
outWidth:图片宽,单位像素.
说完这个类后,我们说说步骤,首先我们可以通过设置一个Options的属性inJustDecodeBounds=true,然后使用BitmapFactory.decodeXXX方法,让options作为参数,这样,我们在不分配内存的情况下,可以通过options读取图片的大小,outWidth和outHeight。其次通过原始图片的大小和你需要图片的大小来计算出需要缩放的比例。最后通过缩放比例值作为options.inSampleSize的值,再次调用BitmapFactory.decodeXXX,在调用方法前一定要设置inJustDecodeBounds=faluse。
- 采用节省内存的编码方式。在Options中,有一个inPreferredConfig属性,这个属性的值是一个Bitmap.Config,我们只需要给inPreferredConfig设置一个节省内存的编码就可以了,例如:options.inPreferredConfig=Bitmap.Config.ARGB_4444.这样就ok了。
举例如下:
计算缩放比例方法(android文档上提供的)
public int calculateInSampleSize(BitmapFactory.Options op, int reqWidth, int reqheight) { int originalWidth = op.outWidth; int originalHeight = op.outHeight; int inSampleSize = 1; if (originalWidth > reqWidth || originalHeight > reqheight) { int halfWidth = originalWidth / 2; int halfHeight = originalHeight / 2; while ((halfWidth / inSampleSize > reqWidth) &&(halfHeight / inSampleSize > reqheight)) { inSampleSize *= 2; } } return inSampleSize; }
从资源图片加载一个大图片,并设置为一个ImageView(iv)的图片。
BitmapFactory.Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(rs, R.drawable.a2,options); options.inPreferredConfig = Bitmap.Config.ARGB_4444; options.inSampleSize = calculateInSampleSize(options, 200, 200); options.inJustDecodeBounds = false; Bitmap bitmap = BitmapFactory.decodeResource(rs, R.drawable.a2,options); iv.setImageBitmap(bitmap);
你可以做一个对比测试,在decodeResource方法中不用options参数和使用options,通过DDMS看看堆内存的使用情况。然后在对比一下使用ARGB_4444和ARGB_8888,堆内存的使用情况。
我在测试的时候,有一个特殊情况,我在drawable-hdpi目录中和drawable-mdpi目录中,存放两张一样的图片(分辨率为3648*2736),采用同样的代码,读取drawable-mdpi中图片,缩放正常,例如inSampleSize=4,屏幕输出的图片分辨率为912*684,但是读取drawable-hdpi目录中的同样一张图片,inSampleSize=4,输出图片的分辨率为608*456,这个十分不解。
相关推荐
合理设置inSampleSize可以避免加载过大图片导致的OOM(Out Of Memory)错误。 2. **内存配置** - `inPreferredConfig`: 指定Bitmap的配置,如ARGB_8888、RGB_565等。ARGB_8888颜色深度最高,但内存消耗也最大;RGB...
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int height = options.outHeight * 200 / options.outWidth; ...
2. 使用`BitmapFactory.decodeFile()`方法加载图片,并传入`BitmapFactory.Options`对象,设置`inSampleSize`。 3. 创建一个适合尺寸的Bitmap对象,并用加载的图片数据填充。 4. 将Bitmap设置到ImageView中。 例如...
在Android开发中,处理`Bitmap`内存溢出问题是一个常见的挑战,尤其是在处理高分辨率或大尺寸图片时。当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap...
理解Android图片处理的底层机制,合理使用`BitmapFactory`和`BitmapFactory.Options`,以及采取适当的内存管理策略,是防止图片加载导致的OOM的关键。在实际开发中,开发者应结合设备特性,灵活运用这些方法,以实现...
在Android开发中,由于系统对每个应用程序分配的内存有限,特别是在加载大图时,很容易触发“Out of Memory”(OOM)错误。这个错误是由于内存不足导致程序无法分配更多的内存空间,进而引发的运行时异常。针对这个...
在 Android 系统中,加载大图片时经常会出现内存溢出的问题,这是因为 Android 系统给图片分配的内存只有 8M,当加载大量图片时,很容易超出这个限制,导致 OOM(Out of Memory)错误。为了解决这个问题,我们需要...
为了解决这个问题,我们需要掌握一些有效的策略来优化图片加载,防止OOM的发生。以下是一些关键知识点: 1. **图片大小与分辨率**:理解图片的像素大小和分辨率至关重要。高分辨率的图片会占用更多内存,因此,尽量...
而在需要加载大图并减少内存占用时,BitmapFactory.Options则是必不可少的工具。 在MatrixAndOptionDemo这个项目中,开发者很可能是为了演示如何结合使用Matrix和BitmapFactory.Options进行图片处理。通过查看源...
在Android开发中,图片处理是必不可少的一部分,...通过正确使用BitmapFactory.Options的inSampleSize属性和调整像素格式,我们可以有效地降低内存占用,防止因图片过大而导致的内存问题,提高应用的稳定性和用户体验。
在Android开发中,处理图片加载是一项常见的任务,但如果不妥善处理,很容易引发内存溢出(Out of Memory,OOM)问题。当应用尝试加载过大或过多的图片时,如果没有进行适当的优化,系统会分配过多内存,导致应用...
"android 加载大图片Demo"是一个示例项目,旨在演示如何有效地处理和加载大尺寸图像,以防止因内存溢出(Out Of Memory,简称OOM)错误而崩溃。在Android应用中,不恰当的大图片处理会消耗大量内存,可能导致应用被...
"安卓Android源码——加载本地图片,绝对不会出现OOM.rar"这个压缩包文件显然是针对这个问题提供了一种解决方案。下面我们将深入探讨Android中如何有效地加载本地图片以避免OOM。 首先,我们需要理解为什么Android...
可以使用`BitmapFactory.Options`类的`inSampleSize`参数来设定图片的加载比例。 **2. 使用BitmapFactory.decodeStream()** 在加载图片时,使用`BitmapFactory.decodeStream()`方法而不是直接从资源文件或网络加载...
"加载本地图片,绝对不会出现OOM.zip"这个文件很可能是包含了一些避免Android应用在加载本地图片时出现内存溢出(Out Of Memory,简称OOM)问题的源码或教程。在Android系统中,由于内存限制,不当的图片处理方式...
// 注意解码时应使用inJustDecodeBounds参数先获取图片尺寸,然后根据屏幕尺寸计算缩放比例,避免加载过大图片 } ``` 四、优化图片加载 1. 使用合适的图片格式:JPEG适用于照片,PNG适用于图标和图形。 2. 图片...
GIF格式的图片包含了连续的帧,当使用默认的Bitmap解码方式时,会一次性加载所有帧到内存中,这样对于大图或者多图场景,内存消耗急剧增加,进而可能导致OOM。 针对这一问题,我们可以采取以下策略来优化GIF加载: ...
"安卓Android源码——加载本地图片,绝对不会出现OOM.zip"这个压缩包文件显然是针对如何避免在Android应用中加载图片时出现内存溢出提供的一种解决方案。下面将详细讲解这个话题。 1. 图片加载引发的OOM问题: 当...