运用BitmapFactory.Options来改善程序加载图片效率和避免内存溢出

android BitmapFactory.Options使用方法详解 BitmapFactory.Options的使用是在加载图片时,就从图片的加载和使用说起  怎样获取图片的大小? 首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高了。 新问题又来了,在通过BitmapFactory.decodeFile(String path)方法将突破转成Bitmap时,遇到大一些的图片,我们经常会遇到OOM(Out Of Memory)的问题。怎么避免它呢? 这就用到了我们上面提到的BitmapFactory.Options这个类。 BitmapFactory.Options这个类,有一个字 立即下载
Fields
public  Bitmap inBitmap If set, decode methods that take the Options object will attempt to reuse this bitmap when loading content.
public int inDensity The pixel density to use for the bitmap.
public boolean inDither If dither is true, the decoder will attempt to dither the decoded image.
public boolean inInputShareable This field works in conjuction with inPurgeable.
public boolean inJustDecodeBounds If set to true, the decoder will return null (no bitmap), but the out...
public boolean inMutable If set, decode methods will always return a mutable Bitmap instead of an immutable one.
public boolean inPreferQualityOverSpeed If inPreferQualityOverSpeed is set to true, the decoder will try to decode the reconstructed image to a higher quality even at the expense of the decoding speed.
public  Bitmap.Config inPreferredConfig If this is non-null, the decoder will try to decode into this internal configuration.
public boolean inPurgeable If this is set to true, then the resulting bitmap will allocate its pixels such that they can be purged if the system needs to reclaim memory.
public int inSampleSize If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.
public boolean inScaled When this flag is set, if inDensity and inTargetDensity are not 0, the bitmap will be scaled to matchinTargetDensity when loaded, rather than relying on the graphics system scaling it each time it is drawn to a Canvas.
public int inScreenDensity The pixel density of the actual screen that is being used.
public int inTargetDensity The pixel density of the destination this bitmap will be drawn to.
public byte[] inTempStorage Temp storage to use for decoding.
public boolean mCancel Flag to indicate that cancel has been called on this object.
public int outHeight The resulting height of the bitmap, set independent of the state of inJustDecodeBounds.
public  String outMimeType If known, this string is set to the mimetype of the decoded image.
public int outWidth The resulting width of the bitmap, set independent of the state of inJustDecodeBounds.

上表是BitmapFactory.Options的字段,现在详细介绍各个字段的作用:

1.inBitmap 这个一般用在Android3.0或者更高版本中,用来管理Bitmap的内存用的。如果设置了这个字段,那么解码图片的时候通过Option类去重用inBitmap这个已经存在的Bitmap的内存去加载新的Bitmap。这意味着,内存的重用从而改进性能,避免重新分配内存。但是运用inBitmap时必须确保一下三点:

  • 重用的Bitmap必须和即将解码的Bitmap的尺寸相同,且是JPEG或者PNG格式。(PS,另外还需要设置options.inMutable = true)
  • BitmapFactory.Options.inPreferredConfig字段设置无效,因为会被重用的Bitmap的configuration所覆盖。
  • 一定要使用解码方法返回的Bitmap,因为重用可能会失败(例如:尺寸不匹配)。
以下是代码示例:

首先需要声明来保持Bitmap(已经用过的Bitmap)

HashSet<SoftReference<Bitmap>> mReusableBitmaps;
private LruCache<String, BitmapDrawable> mMemoryCache;

// 如果是3.0或者以上版本,注意这里必须使用软引用或者弱引用,从Android2.3(API 9)开始系统会更积极的回收被弱引用或者软引用所应用的///资源,在这里只是为了重用Bitmap内存来进一步提高性能,这里必须用软引用或者弱引用。至于图片的复用则用LruCache来实现(是强引用)。
if (Utils.hasHoneycomb()) {
    mReusableBitmaps = new HashSet<SoftReference<Bitmap>>();
}
mMemoryCache = new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize) {

    // 通知释放不需要的缓存,这个方法在每次add新的缓存时调用
    @Override
    protected void entryRemoved(boolean evicted, String key,
            BitmapDrawable oldValue, BitmapDrawable newValue) {
        if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
            //自定义的BitmapDrawable,来降低它里面的引用计数
            ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
        } else {
            // 标准BitmapDrawable.在这里注意,是把已经不用的Bitmap保存起来,这个方法是内存缓存的图片的大小超过了指定的大小,需要抛弃不需要的图片,就是说能够被垃圾回收的Bitmap,不是缓存的Bitmap(在LruCache中的Bitmap)
            if (Utils.hasHoneycomb()) {
                // We're running on Honeycomb or later, so add the bitmap
                // to a SoftReference set for possible use with inBitmap later.
                mReusableBitmaps.add
                        (new SoftReference<Bitmap>(oldValue.getBitmap()));
            }
        }
    }
....
}

复用已经存在的Bitmap的内存空间:

public static Bitmap decodeSampledBitmapFromFile(String filename,
        int reqWidth, int reqHeight, ImageCache cache) {

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filename, options);
    ...

    // 如果运行在Android3.0或者更高的版本,就重用intBitmap的内存空间
    if (Utils.hasHoneycomb()) {
        addInBitmapOptions(options, cache);
    }
    ... //解码方法中的options的inBitmap的值有可能被设置过了,(就是重用Bitmap内存空间成功后会设置)
    return BitmapFactory.decodeFile(filename, options);
}
addInBitmapOptions()方法对options进行了设置,给options的inBitmap设置了在HasSet中保存的Bitmap,这样就重用了已经存在的Bitmap的内存空间。一下是方法的代码:

private static void addInBitmapOptions(BitmapFactory.Options options,
        ImageCache cache) {
    // inBitmap只有和inMutable一块使用才起作用,所以
    options.inMutable = true;

    if (cache != null) {
        //  尝试寻找可重用内存空间的Bitmap
        Bitmap inBitmap = cache.getBitmapFromReusableSet(options);

        if (inBitmap != null) {
            // 如果找到了,就给inBitmap设置值,这样就能用这个Bitmap的内存空间来生成新的Bitmap
            options.inBitmap = inBitmap;
        }
    }
}

// 这个方法是在HasMap中寻找可重用内存空间的Bitmap
protected Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) {
        Bitmap bitmap = null;

    if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
        final Iterator<SoftReference<Bitmap>> iterator
                = mReusableBitmaps.iterator();
        Bitmap item;
	//遍历HasMap中的Bitmap寻找尺寸和要生成的Bitmap尺寸相同的Bitmap
        while (iterator.hasNext()) {
            item = iterator.next().get();

            if (null != item && item.isMutable()) {
                // 检测是否可被重用,就是检测其尺寸(长和宽)是否和要新生成的Bitmap的尺寸(长和宽)相同,
                if (canUseForInBitmap(item, options)) {
                    bitmap = item;

                    // 把这个能被重用内存空间的Bitmap从HashMap中删除,防止被两个以上重用导致的问题。
                    iterator.remove();
                    break;
                }
            } else {
                // Remove from the set if the reference has been cleared.
                iterator.remove();
            }
        }
    }
    return bitmap;
}
canUseForInBitmap()这个方法就是检测options中目标Bitmap的尺寸(是原始尺寸通过和inSampleSize计算能够得到要显示的Bitmap的尺寸)和HashMap中Bitmap的尺寸(由于是以前生成过的Bitmap所以一定是缩放过的)是否相同。一下是代码实现:

private static boolean canUseForInBitmap(
        Bitmap candidate, BitmapFactory.Options targetOptions) {
    int width = targetOptions.outWidth / targetOptions.inSampleSize;
    int height = targetOptions.outHeight / targetOptions.inSampleSize;

    // 如果尺寸(长和宽)相同,就返回true
    return candidate.getWidth() == width && candidate.getHeight() == height;
}


PS:在这里补充一点,使用 BitmapFactory.decode* 方法解码生成图片,除了加载app自带的图片外,其他的都需要在非主线程中进行。

先写到这里,还用工作啊。。。。

NOAA气象数据下载攻略 各方搜寻气象数据下载途径,发现网上最多的就是从NOAA下载,但是中途有尝试过很多次都没有下载到,每次都是显示不可用,今天终于下载成功了,特此记录。 首先我是从这个网址进入的:National Centers for Environmental Information (NCEI) formerly known as National Climatic Data Center (NCDC) | NCEI offers access to the most significant archives of oc 阅读详情

相关推荐

Windows Server 2019/2022 RDS 授权实战:3步激活许可证服务器,解决120天宽限期问题

本文详细介绍了Windows Server 2019/2022 RDS授权实战,提供3步激活许可证服务器的完整解决方案,解决120天宽限期问题。涵盖远程桌面授权服务器配置、许可证激活方法及组策略设置,确保企业合规使用远程桌面服务。

weixin_32705179的博客 973

BitmapFactory.Options中参数使用

文章目录使用场景使用方式代码 使用场景 android开发的过程中,很多时候我们所需要的图片大小比原图小,这时候我们就没有必要加载原图进行显示毕竟大图占用的内存要大。 使用方式 使用BitmapFactory.Options的inSampleSize来调整图片的尺寸, 查看inSampleSize的官方注解,inSampleSize 当采样率大于一的时候 ,长和宽对应变为原来的 1/inSampleSize,对应的像素数量减少 1/(inSampleSize^2),bitmap的大小相应的也缩小为 1/(i

liu_12345_liu的博客 3671

复合材料RVE建模与力学性能分析实战指南

代表体积元(RVE)建模是复合材料多尺度分析的核心技术,通过建立微观结构与宏观性能的定量关联,可准确预测材料力学行为。本文基于ABAQUS平台,详细解析三材料(纤维/基体/界面相)RVE建模全流程,包括参数化几何建模、周期性网格划分策略、材料属性定义技巧等关键技术环节。针对碳纤维增强环氧树脂等典型复合材料,提供网格控制参数建议和材料参数参考表,并重点说明周期性边界条件的实现方法与验证标准。通过Python脚本自动化处理和优化分析流程,可显著提升计算效率,为复合材料设计提供可靠仿真依据。

weixin_34062469的博客 549

BitmapFactory.Options

转载:http://blog.csdn.net/guolin_blog/article/details/9316683

学习点滴的专栏 1234

从报错到定位:Memtest86 DQ位算法解析与实践指南

本文深入解析了Memtest86内存测试工具报错信息的解读方法,重点介绍了通过地址解析、数据转换、位比对和DQ定位四步算法,精准锁定故障DQ位的实践流程。文章以DDR4和DDR5为例,详细拆解了从十六进制报错到二进制比对的完整步骤,并提供了从单个报错分析到故障模式诊断的进阶指南,帮助用户将抽象的报错信息转化为具体的维修或排查依据。

sre5engineer的博客 486

快速了解GPU分布通信技术:PCIe、NVLink与NVSwitch

PCIe(Peripheral Component Interconnect Express)是一种高速串行计算机扩展总线标准,广泛用于连接计算机的各种硬件设备。PCIe4.0是目前较为先进的版本,提供了高达64GB/s的带宽。InfiniBand是一种用于高性能计算的高速互连技术,通过交换机在节点之间直接创建一个专用的受保护通道。InfiniBand适配器通过PCIe接口连接到CPU,另一端通过InfiniBand网络端口连接到InfiniBand子网。

全世界的博客 7543

Android 图片压缩也即生成缩略图方法

Android 图片压缩也即生成缩略图方法   Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。本文从应用的角度,着重介绍怎么用Bitmap来实现这些功能。   一、Bitmap的生成 1.1 BitmapFactory decode出Bitmap     Bitm

glen1943的专栏 1034

DIY玩家必备:用SSS1623芯片打造高性价比USB麦克风(附完整电路图)

本文详细介绍了如何利用SSS1623芯片DIY高性价比USB麦克风,包括元件选型、电路设计、PCB布局及调试技巧。通过完整的电路参考设计和实用建议,帮助电子爱好者打造专业级录音设备,实现免驱动即插即用功能。

weixin_29166013的博客 239

图片加载2:BitmapFactory.Options详解

(1)常用属性 BitmapFactory.Options options = new BitmapFactory.Options(); //默认值为false,如果设置成true,那么在解码的时候就不会返回bitmap,即bitmap = null。 options.inJustDecodeBounds = false; //可以复用之前用过的bitmap options.inBitma...

qijingwang的博客 668

[Linux项目实践] LCD Panel的硬件分析及调试

LCD硬件分析 项目使用3.5” TFT-LCD并且支持触摸控制。LCD的硬件可从几个方面学习:1)查看LCD的硬件连线。2)查看数据手册了解寄存器的控制。3)查看LCD DATASHEET了解硬件操作 1)LCD硬件连线 在图中有33个引脚,22根数据引脚和9根控制引脚。 LCD的工作原理:像素点是从左至右,从上至下逐个显示,LCD控制寄存器会从从内存中的framebuffer通

Terry_Yuan的技术专栏 3023

Open3D——RANSAC 三维点云空间直线拟合【2025最新版】

使用RANSAC算法在点云数据中拟合三维空间直线的python代码实现。博客长期更新,本文最新更新时间为:2025年3月23日。

点云侠的博客 7354

Android使用BitmapFactory高效加载大图,防止OOM

基于以上,当我们决定是把原图加载进内存还是压缩图加载进内存的时候,有几点是需要考虑的: 大概的估算一下这张图片占用多少内存。 展示图片的控件的实际像素大小。 考虑一下当前设备的屏幕尺寸和屏幕分辨率。 这里我简单的说一下第二点和第三点。假设使用ImageView进行加载图片,很多时候ImageView没有图片的尺寸那么大,这个时候你把原始图片加载进来再设置给ImageV...

一抹离愁 948

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

BitmapFactory.Options避免 内存溢出 OutOfMemoryError的优化方法

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source...

weixin_33937499的博客 100

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

图片压缩和缓存高效加载规避oom总结

高效加载大图片查看每个应用程序最高可用内存是多少:int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); Log.d("TAG", "Max memory is " + maxMemory + "KB"); BitmapFactory这个类提供了多个解析方法(decodeByteArray, decodeFile, de

微凉一季的专栏 3330

android 解决图片加载内存溢出

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 sou

1428

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

BitmapRegionDecoder 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitma...

augfun的博客 989

android地图图片加载,Android 图片加载(一)高效加载Bitmap 基础篇

由于Bitmap的特殊性以及Android对单个应用所规定的最大内存限制,我们在同时加载大量Bitmap时很容易发生内存溢出,即我们通常所说的OutOfMemoryError(OOM),因此高效加载Bitmap就成为了每个Android开发者的必备技能。在学习如何高效地加载Bitmap之前,首先介绍一下如何加载一个Bitmap。我们都知道,Bitmap在Android中通常指的是一张图片,那么如何...

weixin_42510924的博客 748

Android使用BitmapFactory.Options解决加载大图片内存溢出问题

转载至 http://blog.163.com/gobby_1110/blog/static/292817152012111424410578/ 由于Android对图片使用内存有限制,若是加载几兆的大图片便内存溢出。Bitmap会将图片的所有像素(即长x宽)加载到内存中,如果图片分辨率过大,会直接导致内存溢出(java.lang.OutOfMemoryError),只有在BitmapFac

Justin Harmon 406

android图片加载

图片占内存容量计算公式为: 图片所占内存大小 = 图片长度(像素) * 图片宽度(像素) * 一个像素所占内存空间(单位:字节) 一般地,一个象素所占内存空间根据机器颜色数(专业词汇叫色深Color Depth)来决定:(1)Nokia 老S40机器 颜色数为4096色,就是2^12, 一个象素所占内存空间为1.5个字节;(2)Nokia S40新版 机器和 S60机器 颜色数为65536...

乌龟赛跑 660

Android图片的高效加载与缓存策略

一、简介 Bitmap在Android中指的是一张图片。 BitmapFactory提供了四种方法来加载图片: decodeFile----------从文件加载一个Bitmap对象 decodeResource --从资源加载一个Bitmap对象 decodeStream -----从输入流加载一个Bitmap对象 decodeByteArray--从字节数组加载一个Bitmap对象 ...

u013087553的博客 900

bitmapfactory.options 优化内存小问题

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的

zj的博客 422
上一篇: dp和px,那些不得不吐槽的故事——Android平台图片文字元素单位浅析
下一篇: Android Bitmap内存管理,解决内存溢出问题(1)之自定义BitmapDrawable
恶魔果实
博客等级 码龄15年 6粉丝 13原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值