前言:”安得广厦千万间,大庇天下寒士俱欢颜“——杜甫。在帝都住的朋友们都可能会遇到租房子困难的问题(土豪请无视),找房子真是力气活,还耗费时间,占用我宝贵的写博客时间,没办法,谁让咱没钱还想住的好点,努力努力挣钱!!!以上发点牢骚,现在进入正题。上一篇博客《Bitmap那些事之内存占用计算和加载注意事项》,写了Bitmap基础知识和使用Bitmap需要知道的注意事项,这一片博客我会写在Android应用中Bitmap的创建和加载。
 
1、BitmapFactory使用:
 
说到图片的加载就必须说BitmapFactory,看名字就知道他的作用了,就是一个生产Bitmap的工厂,下图是它的一些工厂方法:
 
 
从上图可以看到BitmapFactory可以使用存储Bitmap数据的数组,Bitmap的资源ID,Bitmap文件等做为数据源来创建Bitmap对象,具体情况看你程序中提供的数据源是哪一种。这些方法中对每一种数据源都提供了两个方法,这里需要注意一下BitmapFacotry.Options参数,它是BitmapFactory的内部类,有一些成员变量含义需要记一下,下面就来说说。
 
2、BitmapFacotry.Options的inJustDecodeBounds 参数使用:
为了节省内存,很多情况下原图片都要经过缩放处理,根据控件的尺寸来处理成对应尺寸的图片,这时使用BitmapFactory创建Bitmap,很多情况下都会使用下面的代码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
注意上面中的options.inJustDecodeBounds =true的inJustDecodeBounds参数,为了避免我翻译的不准确我这里先贴出来google的原文: If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels。用我的话来说就是在decode的时候不给这个bitmap的像素区分配内存,除了这个区别Bitmap的其他信息你都能获取到。这样就有很大的意义,你既没有消耗内存又拿到了图片的信息,为你下一步图片处理提供帮助。
 
3、BitmapFacotry.Options的inSampleSize参数使用:
 
上一步你已经获取到图片的原始尺寸了,下一步就是要把原图缩放到你需要的大小,可以通过inSampleSize参数来设置,google原文的解释是:If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder will try to fulfill this request, but the resulting bitmap may have different dimensions that precisely what has been requested. Also, powers of 2 are often faster/easier for the decoder to honor.(不管你看不看英文文档我还是要把google原文贴出来,我英文比较烂,翻译的不一定准确),大概意思就是说这个参数可以调节你在decode原图时所需要的内存,有点像采样率,会丢掉一些像素,值是大于1的数,为2的幂时更利于运算。举个例子:当 inSampleSize == 4 时会返回一个尺寸(长和宽)是原始尺寸1/4,像素是原来1/16的图片。这个值怎么计算呢?
public static int calculateInSampleSize(
BitmapFactory.Options options,int reqWidth,int reqHeight){
// Raw height and width of image
finalint height = options.outHeight;
finalint width = options.outWidth;
int inSampleSize =1; if(height > reqHeight || width > reqWidth){ finalint halfHeight = height /2;
finalint halfWidth = width /2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while((halfHeight / inSampleSize)> reqHeight
&&(halfWidth / inSampleSize)> reqWidth){
inSampleSize *=2;
}
} return inSampleSize;
}

在decode的时候先设置options.inJustDecodeBounds =true,获取到图片参数后再设置为false,这就是decode时的技巧,下面就把完整代码贴出来,可以作为工具方法来使用:

public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId,
int reqWidth,int reqHeight){ // First decode with inJustDecodeBounds=true to check dimensions
finalBitmapFactory.Options options =newBitmapFactory.Options();
options.inJustDecodeBounds =true;
BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set
options.inJustDecodeBounds =false;
returnBitmapFactory.decodeResource(res, resId, options);
}

上面的方法来自于google官网,没必要进行修改,这就是程序员的拿来主义吧,关键在于要知道为什么这么写。下面是我自己写的一个方法可以直接拿来当工具用。

    /**
* 对图片进行压缩,主要是为了解决控件显示过大图片占用内存造成OOM问题,一般压缩后的图片大小应该和用来展示它的控件大小相近.
*
* @param context 上下文
* @param resId 图片资源Id
* @param reqWidth 期望压缩的宽度
* @param reqHeight 期望压缩的高度
* @return 压缩后的图片
*/
public static Bitmap compressBitmapFromResourse(Context context, int resId, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
/*
* 第一次解析时,inJustDecodeBounds设置为true,
* 禁止为bitmap分配内存,虽然bitmap返回值为空,但可以获取图片大小
*/
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(context.getResources(), resId, options); final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
options.inSampleSize = inSampleSize;
// 使用计算得到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(context.getResources(), resId, options);
}
以上就是Bitmap在Android中加载到内存中的一些小技巧,大家是不是以后就能很好的应用起来,避免因为加载图片引起OOM这样的问题呢?如果您有更好更棒的方法可以给我留言或者添加我的微信公众号:coder_online。大家共同学习,共同进步,赚钱不再为房子发愁。你可以方便的扫描下面的二维码进行添加:
                                                            

Android Bitmap那些事之如何优化内存的更多相关文章

  1. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  2. Bitmap那些事之内存占用计算和加载注意事项

    前言:本来我是做电视应用的,但是因为公司要出手机,人员紧张,所以就抽调我去支援一下,谁叫俺是雷锋呢!我做的一个功能就是处理手机中的应用ICON,处理无非就是美化一下,重新与底板进行合成和裁剪,用到了很 ...

  3. Android性能优化-内存优化

    原文链接 Manage Your App’s Memory 前言 在任何软件开发环境中,RAM都是比较珍贵的资源.在移动操作系统上更是这样,因为它们的物理内存通常受限.尽管在ART和Dalvik虚拟机 ...

  4. Android 性能优化 ---- 内存优化

    1.Android内存管理机制 1.1 Java内存分配模型 先上一张JVM将内存划分区域的图 程序计数器:存储当前线程执行目标方法执行到第几行. 栈内存:Java栈中存放的是一个个栈帧,每个栈帧对应 ...

  5. 谷歌发布 Android 8.1 首个开发者预览版,优化内存效率

    今晨,谷歌推出了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化,其中包含对 Android Go (设备运行内存小于等于 1 GB)和加速设备上对机器学习的全新神经网 ...

  6. 【腾讯bugly干货分享】Android自绘动画实现与优化实战——以Tencent OS录音机波形动

    前言 本文为腾讯bugly的原创内容,非经过本文作者同意禁止转载,原文地址为:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1180 ...

  7. Android——BitMap(位图)相关知识总结贴

    Android中文API(136) —— Bitmap http://www.apkbus.com/android-54644-1-1.html Android 4.0 r1 API—Bitmap(S ...

  8. Android开发笔记——常见BUG类型之内存泄露与线程安全

    本文内容来源于最近一次内部分享的总结,没来得及详细整理,见谅. 本次分享主要对内存泄露和线程安全这两个问题进行一些说明,内部代码扫描发现的BUG大致分为四类:1)空指针:2)除0:3)内存.资源泄露: ...

  9. (转)Android开发:性能最佳实践-管理应用内存

    翻自:http://developer.android.com/training/articles/memory.html 在任何软件开发环境中,RAM都是宝贵的资源,但在移动操作系统中更加珍贵.尽管 ...

随机推荐

  1. 【转】selenium及webdriver的原理

    主要内容转自:http://blog.csdn.net/ant_ren/article/details/7968582和http://blog.csdn.net/ant_ren/article/det ...

  2. Android Recovery Ui 分析

    Android  recovery和android本质上是两个独立的rootfs, 仅仅是recovery这个rootfs存在的意义就是为android这个rootfs服务,因此被解释为Android ...

  3. ubuntu完美卸载JDK

    要删除 OpenJDK (如果已安装的话).首先,检查是安装的哪个 OpenJDK包. # dpkg --list | grep -i jdk 移除 openjdk包: # apt-get purge ...

  4. Out of resources when opening file 错误解决

    mysqldump: Got error: 23: Out of resources when opening file ‘./mydb/tax_calculation_rate_title.MYD’ ...

  5. SAO总结

    Application Structure Web App-------------------------------------------------------------->Serve ...

  6. Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换

    一.问题描写叙述 本系列将结合案例应用,陆续向大家介绍一些Android典型界面的设计,首先说说tab导航,导航分为一层和两层(底部区块+区域内头部导航).主要实现方案有RadioGroup+View ...

  7. PS拾色器(前景色背景色)快捷键

    快捷键 I 是拾色器 X 是前后色切换

  8. 给指针malloc分配空间后就等于数组吗?

    首先回答这个的问题:严格的说不等于数组,但是可以认为它是个数组一样的使用而不产生任何问题.不过既然这样,那它应该算是个数组吧.所以,一般我们都用“动态数组”这种名字来称呼这种东西. 要讲清楚这个东西, ...

  9. Android实现定时器的方法

    一.Handler 和 Thread package com.lstech.app; import android.app.Activity; import android.os.Bundle; im ...

  10. C++与正态分布

    正态分布(Normal distribution)又名高斯分布(Gaussiandistribution).若随机变量X服从一个数学期望为μ.方差为σ^2的高斯分布,记为N(μ,σ^2).其概率密度函 ...