BitmpaFactory和BitmapFactory.Options详解及优化解码图片时使用的内存

Android13 BitmapFactory decodeStream流程分析 BitmapFactory的decodeStream()方法用于从输入流中解码图像,并返回一个Bitmap对象。 阅读详情

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

因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,
decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,
无需再使用java层的createBitmap,从而节省了java层的空间。
如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 
使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

另外,以下方式也大有帮助:
1. InputStream is = this.getResources().openRawResource(R.drawable.pic1);
     BitmapFactory.Options options=new BitmapFactory.Options();
     options.inJustDecodeBounds = false;
     options.inSampleSize = 10;   //width,hight设为原来的十分一
     Bitmap btp =BitmapFactory.decodeStream(is,null,options);
2. if(!bmp.isRecycle() ){
         bmp.recycle()   //回收图片所占的内存
         system.gc()  //提醒系统及时回收
}

以下奉上一个方法:

Java代码

   1. /**
   2.  * 以最省内存的方式读取本地资源的图片
   3.  * @param context
   4.  * @param resId
   5.  * @return
   6.  */  
   7. public static Bitmap readBitMap(Context context, int resId){  
   8.     BitmapFactory.Options opt = new BitmapFactory.Options();  
   9.     opt.inPreferredConfig = Bitmap.Config.RGB_565;   
  10.     opt.inPurgeable = true;  
  11.     opt.inInputShareable = true;  
  12.        //获取资源图片  
  13.     InputStream is = context.getResources().openRawResource(resId);  
  14.         return BitmapFactory.decodeStream(is,null,opt);  
  15. }

 

优化Dalvik虚拟机的堆内存分配

对 于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用 dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体 原理我们可以参考开源工程,这里我们仅说下使用方法:   private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate时就可以调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

 

 

介绍一下图片占用进程的内存算法吧。
android中处理图片的基础类是Bitmap,顾名思义,就是位图。占用内存的算法如下:
图片的width*height*Config。
如果Config设置为ARGB_8888,那么上面的Config就是4。一张480*320的图片占用的内存就是480*320*4 byte。
前面有人说了一下8M的概念,其实是在默认情况下android进程的内存占用量为16M,因为Bitmap他除了java中持有数据外,底层C++的 skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M。这个可以调整,编译源代码时可以设置参数。







加载和显示图片是很消耗内存的一件事,BitmapFactory.Options 类,  允许我们定义图片以何种方式如何读到内存,

[java]  view plain copy
  1. BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
  2. bmpFactoryOptions.inSampleSize = 8;  
  3. Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);  
  4. imv.setImageBitmap(bmp);  

上面的代码使图片变成原来的1/8.


[java]  view plain copy
  1. //imv = (ImageView) findViewById(R.id.ReturnedImageView);  
  2.         Display currentDisplay = getWindowManager().getDefaultDisplay();  
  3.         int dw = currentDisplay.getWidth();  
  4.         int dh = currentDisplay.getHeight();  
  5.           try  
  6.        {  
  7.         BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
  8.         bmpFactoryOptions.inJustDecodeBounds = true;  
  9.         Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().  
  10.                 openInputStream(imageFileUri), null,  bmpFactoryOptions);  
  11.   
  12.         int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);  
  13.         int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);  
  14.   
  15.         Log.v("HEIGHRATIO", ""+heightRatio);  
  16.         Log.v("WIDTHRATIO", ""+widthRatio);  
  17.   
  18.         if (heightRatio > 1 && widthRatio > 1)  
  19.         {  
  20.             bmpFactoryOptions.inSampleSize =  heightRatio > widthRatio ? heightRatio:widthRatio;  
  21.         }  
  22.         bmpFactoryOptions.inJustDecodeBounds = false;  
  23.         bmp = BitmapFactory.decodeStream(getContentResolver().  
  24.                 openInputStream(imageFileUri), null,  bmpFactoryOptions);  
  25.            returnedImageView.setImageBitmap(bmp);  
  26.        }  
  27.        catch (FileNotFoundException e)  
  28.        {  
  29.            Log.v("ERROR", e.toString());  
  30.   
  31.        }  


上面的代码让图片根据窗口大小改变


BitmapFactory.decodeStream方法返回null的错误分析 这个问题其实早就遇到了,由于停了几天电无法工作,今天就把这问题记录下分享下。利用BitmapFactory加载网络中的图片时,使用decodeStream方法会返回null的错误。主要是由于下面几个原因导致的: 流已经关闭 decodeStream调用了两次 decodeStream的BUG(本文不讨论,详见参考文章) 这个问题很有意思,刚开始遇到的时候在国内外到找到许多不同的解决方法 阅读详情

相关推荐

用Keil5给CH552G编程:手把手配置8051开发环境+LED闪烁实战

本文详细介绍了如何使用Keil5为CH552G单片机配置8051开发环境,并完成LED闪烁实战。从获取必要软件、安装WCH器件库到创建工程、编写程序及烧录,手把手指导开发者避开常见陷阱,特别适合从STC转向CH552G的开发者。

weixin_30733003的博客 539

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

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

799

香橙派5使用RK3588S内置NPU加速yolov5推理,实时识别数字达到50fps

香橙派5采用了RK3588S,内置的NPU达到了6Tops的算力,博主这里记录一下自己的踩坑过程,好不容易做出来的不能以后忘记了(手动狗头)。这里博主还在B站上发布了效果视频,大家感兴趣的话可以看一下。其中解决了先验框标注位置不对,或者出现非常多的框的问题

weixin_51651698的博客 2万+

Android性能优化之Bitmap的内存优化

1、BitmapFactory解析Bitmap的原理 BitmapFactory提供的解析Bitmap的静态工厂方法有以下五种: Bitmap decodeFile(...) Bitmap decodeResource(...) Bitmap decodeByteArray(...) Bitmap decodeStream(...) Bitmap decodeFileDescriptor(

Liyunlong 1206

QQ技术大总结

此贴只是一些对q友有用的东西,也许有人知道,高手勿喷。进如正题~ 1. 进入访问受限的qq空间 在地址栏里输入 http://qqxoo.com/main.html?qqid=qq号这样就可能看对方的空间 http://qqshow-user.tencent.com/qq号/11/00 看mm的qq绣 http://shuqian.qq.com/qq号/ qq书签 ...

weixin_33845881的博客 1273

保姆级教程:RK3588部署yolo目标检测模型

RK3588部署yolo目标检测模型非常详细的保姆级教程

ling913的专栏 5488

Android Bitmap详解

一、Bitmap: Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。 常用方法: public void recycle()  // 回收位图占用的内存空间,把位图标记为Dead public fina...

假装你是大灰狼的专栏 6086

某音播放量查询,播放量接口研究,最新版本抓包,修改SO文件绕过SSL

本教程适用于某音27.8,64位版本,32为版本及某音旁侧版本修改方法大同小异,部分旁侧版本修改之后模拟器可能无法抓包,真机测试均可正常抓包,此方法修改后绝大部分包可以正常抓取,但部分包无法抓取,例如验证码,内置浏览器功能,如需抓取此类包可通过 Postern + Charles 实现。

byalipus的博客 1万+

Android性能优化系列之Bitmap图片优化

在Android开发过程中,Bitmap往往会给开发者带来一些困扰,因为对Bitmap操作不慎,就容易造成OOM(Java.lang.OutofMemoryError - 内存溢出),本篇博客,我们将一起探讨Bitmap的性能优化。为什么Bitmap会导致OOM?1.每个机型在编译ROM时都设置了一个应用堆内存VM值上限dalvik.vm.heapgrowthlimit,用来限定每个应用可用的最大内

一个码农的博客 1万+

Oracle登录报错ORA-12560?5分钟搞定TNS协议适配器错误的完整修复指南

本文详细解析了Oracle登录报错ORA-12560(TNS协议适配器错误)的成因与解决方案。从基础服务检查到高级网络配置排查,提供了一套完整的修复流程,帮助数据库管理员快速解决连接问题,确保Oracle数据库的稳定运行。

weixin_29278805的博客 524

【ArcGIS微课1000例】0066:图像融合(全色+多光谱)操作案例教程

图像融合是指将不同类型传感器的影像进行融合,既能使图向具有较高的空间分辨率,又具有多光谱的特性。除了遥感软件如Erdas能进行图像融合,ArcGIS软件也可以进行图像融合等图像增强操作。

智慧空间实验室 3079

Bitmap内存优化--使用BitmapFactory.options及SoftReference解决OutOfMemory问题

解决Bitmap经常出现OutOfMemory: Android手机分配给App的内存并不是无限的(即最大可用内存),而是有固定限制的, Bitmap会非常占用内存,导致OutofMemory问题,有三个策略:策略一:对bitmap进行缩放,直接降低在内存中的存储空间; 策略二:通过SoftReferences(软引用)策略; 策略三:开启线程进行异步加载图片,避免出现卡顿现象。

我的Android合伙人是你么 904

2024年游戏策划最新面试题及答案

1. **游戏策划**:负责游戏设计和开发的创意和技术过程。2. **主要职责**:设计游戏玩法、故事、角色、世界等。4. **游戏机制**:定义玩家如何与游戏世界互动的规则。13. **引人入胜的角色**:深入的背景故事、个性特征。3. **游戏平衡**:确保游戏公平、有趣且具有挑战性。7. **RPG特点**:角色发展、故事驱动、玩家选择。12. **关卡设计技巧**:挑战性、流动性、视觉引导。11. **游戏关卡设计**:创建游戏世界的不同阶段。5. **游戏循环**:玩家在游戏中重复的行为模式。

guo162308的博客 2321

Bitmap优化

1. 一个进程的内存可以由2个部分组成:`native和dalvik`,`dalvik`就是我们平常说的`java`堆,我们创建的对象是在这里面分配的,而`bitmap`是直接在`native`上分配的。 一旦内存分配给`Java`后,以后这块内存即使释放后,也只能给`Java`的使用,所以如果`Java`突然占用了一个大块内存,即使很快释放了,`C`能用的内存也是16M减去`Java`最大占用

梵依然的专栏 849

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android性能优化系列:Bitmap

文章目录1 Bitmap简介2 Bitmap的计算2 Bitmap优化的几种方式2.1 选择适合的目录存放图片(drawable/mipmap)2.2 解码方式2.3 压缩方式2.4 调整缩放比例 1 Bitmap简介 Bitmap 在Android开发中作为图片信息的载体,比如在列表、Banner、Splash还是其他界面,图片都是在内存占用中比例比较大的,没有妥善处理很容易导致OOM(Out ...

Vincent的博客 2947

IDEA的使用指南

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

内存优化二Bitmap优化

一张图片Bitmap所占用的内存 = 图片长度 x 图片宽度 x 一个像素点占用的字节数 而Bitmap.Config,正是指定单位像素占用的字节数的重要参数。 其中,A代表透明度;R代表红色;G代表绿色;B代表蓝色。ALPHA_8 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度 ARGB_4444 表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节 ARGB_8888 表示32位ARGB位图,即A=8,R=8

u012845099的博客 1527

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

android decode方法,Android应用开发Android 加载本地图片decodeStream()方法OOM

本文将带你了解Android应用开发Android 加载本地图片decodeStream()方法OOM,希望本文对大家学Android有所帮助。Android 加载本地图片decodeStream()方法OOM。public static Bitmap getLocalBitmap(String url) {try {FileInputStream fis = new FileInputStr...

weixin_34118050的博客 640

Android:BitmapFactory.decodeStream Bitmap的内存优化OutOfMemory异常以后Crash闪退

Android:BitmapFactory.decodeStream 异常OOM闪退

u013083465的专栏 2127

Android加载大图片内存溢出的问题总结

原文地址:Android加载大图片内存溢出的问题总结作者:風中靜思_2011 写Android代码也有那么三四个月的时间了,也一直都是菜鸟,很多东西都只是拿来就用,也没有想太多的细节问题。 之前在程序中遇到图片资源的时候,总是使用BitmapFactory.decodeResource来设置图片资源,也没发现什么问题。前段时间在写一个动态壁纸程序的时候,可能图片资源比较多,毕竟手机...

weixin_30367169的博客 197

BitmapFactory.decodeStream 内存溢出java.lang.OutOfMemoryError

BitmapFactory.decodeStream 内存溢出java.lang.OutOfMemoryError 先说原因吧,BitmapFactory.decodeStream 内存溢出java.lang.OutOfMemoryError 是因为 使用Content Provider android.content.ContentResolver.openInputStream 去取数据时,因为图片过大就会报错,而不是bitmap显示时报错。 所以在使用前压缩的思路是错误了。

门徒07的博客 4671

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

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

u013087553的博客 900

BitmapFactory.decodeStream读取Asset文件出现decoder->decode returned false错误

BitmapFactory.decodeStream(InputStream is)从Asset文件中读取图像文件时,会出现decoder->decode returned false错误,可能的问题之一是读取的文件类型为jpg格式的,将图片格式转码为gif格式即解决问题。 附1:读取Asset文件(以图像文件为例)的代码: AssetManager am = ct.getResour

EsonJohn的博客 1956

BitmapFactory.decodeStream(inputStream,null,options)返回为null

BitmapFactory.decodeStream(inputStream,null,options)返回为null

the_spring的博客 2496

BitmapFactory.decodeStream使用inJustDecodeBounds参数解析网络流的问题

BitmapFactory.Options的inJustDecodeBounds设置为false使BitmapFactory

oHeHeHou的专栏 5819
上一篇: Android TextView跑马灯效果
下一篇: 自定义实现圆形播放进度条
gwpJava
博客等级 码龄14年 11粉丝 91原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值