当前位置:首页 » 安卓系统 » androidbitmap文件

androidbitmap文件

发布时间: 2023-08-23 11:15:50

Ⅰ Android Bitmap理解

参考:
Android Bitmap 详解:关于 Bitamp 你所要知道的一切

Android Bitmap(位图)详解

图片是由大量且有限个数的像素点组成。把一张图片通过bitmap的方式创建到内存中,实际上就是在内存中创建了一个叫做Bitmap的对象,然后把 图片所有像素 解码后的数据存放在Bitmap对象里面,Bitmap就拥有了图片的宽高,透明度,颜色值等数据。所以Bitmap的创建是通过BitmapFactory.decodeXxx()。

Config是Bitmap类中的枚举类。像素由ARGB四个颜色通道组成。Config描述位图中像素的存储方式。 这里的存储方式,无非就是对颜色通道和用多大的容器(bit)来存储的排列组合。所以config会影响图片透明度,占用内存大小,保存成文件的大小,图片质量。
Config的字母表示该配置存储的像素的颜色通道,数字表示对应通道的数据用多少位来存储。

ALPHA_8:表示只存储alpha通道,使用8bit(1字节)的内存(容器)来存储一个像素。
RGB_565:表示存储RGB三个通道,分别使用5bit,6bit,5bit的内存(容器)来存储一个像素。
ARGB_4444:表示存储ARGB四个通道,每个通道都是以4bit的内存(容器)来存储一个像素。
ARGB_8888:表示存储ARGB四个通道,每个通道都是以8bit的内存(容器)来存储一个像素。

所以,ARGB_8888配置占用内存最大,图片质量最高。
图片压缩的一个思路就是降低图片的配置。

总内存 = 宽的像素数 × 高的像素数 × 每个像素点占用的大小
注:
1 byte = 8 bit
1 KB = 1024 byte

Ⅱ Android Bitmap 内存以及OOM问题讨论

都知道在悔敏厅Android中, 每个应用所使用的内存是有限的,现在的手机通常最大的内存使用为256M, 目前还没发现Android中一个应用的最大内存分配超过256M的(经测试华为手机的最大内存是385M)

相关API:

ActivityManager.getMemoryClass(),首先获取系统服务中的ActivityManager

如下:

(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

可以获取到相关信息

最近一直被项目的OOM问题困扰, 在网上查阅相关资料,前前后后读了不下于30篇,这些篇幅讲解的东西都是千篇一律,并没有解决到实际问题

也在慕课网学习了内存优化章节

这是慕课网讲师的PPT,我截屏的

这里来仔细分析一下:

第一个,  注意临时Bitmap对象的及时回收, 来碧隐看下相关API

直接上图

经过我无数次的使用Android studio工具自带的MAT分析工具后, 得出一个很严谨的结论, 此方法并不奏效...

Android中Bitmap的内存存放在堆区, Google 的Bitmap的recycle方法注释也可以了解到

Android历史版本不是很清楚, 据说Android3.0之前Bitmap是存放在native区域,可以进行手动释放,然而3.0之后Bitmap是存放在Java层的堆区,没错是heap, 内存管理直接交由系统GC管理,你还这样释放资源有意义?无非是给自己的一点心理安慰罢了, 告诉你没卵用

又有人在说要释放内存使用System.gc() ???  对就是主动触发垃圾回收,这个API是开发者自行调用的吗?那么系统管理内存还有什么意义?这不是误人子弟吗,这个API不能调用的, 因为没卵用的, 具体自己参照MAT工具自行分析.即便垃圾回收真的被触发了, 所有线程停滞由系统来清理垃圾, 造成的后果是严重卡顿!!!

再看一个API:

我在网上苦苦追寻内存过高的问题后,发现了这个API,经过无数次实践后我得出一个结论,没卵用...开发者可以抛弃它

综上所诉, 第一点讲解的内存优化拿塌问题可以直接PASS掉, 无非给自己一点心理安慰: 我已经处理好了内存问题, 程序不会OOM?

第二点. 避免Bitmap的浪费

直接说结论, 这个是非常行之有效的,并且是一定能解决问题的

具体怎么操作呢? 自己实现LruCache这个类, 就是这么弄, 原理就是解码复用, 在内存中已经解码好的Bitmap直接拿出来使用, 没有的在加载到内存进行解析, 这个非常有效,但是并不能让你避免OOM

第三点, try-catch某些大内存分配的操作

这点上,我又要开始疑问了, 我Java功底不是很好

Java中发生内存溢出时,抛出的是OutOfMemoryError, 它的父类是VirtualMachineError

这玩意能catch住? 它属于Error范畴, 你能捕获?请Java大神出来说一下,我解释不清楚

第四点, 加载Bitmap 缩放比例, 解码格式, 局部加载

先来分析一下缩放比例:

按照市面上主流的手机分辨率来分析现在Android主流的分辨率是1920X1080, 如果一个ImageView控件刚好就是屏幕全屏,怎么说?直接占用掉8M内存, 想想一个实际的需求情况

一个查看大图的页面, 不断的关闭,打开查看新的大图,问题就来了,内存一直在暴增,迟早会突破界限OOM掉

分辨率是2K屏呢? 更恐怖了, 随着手机设备的屏幕分辨率提升, 加载图像需要的内存也是倍增的, 因为应用的最大内存并没有增加

结论: 缩放比例可以有效的降低内存占用问题, 但不是绝对的救命稻草, 该缩放的还是要缩放,而且必须缩放,就是采样  现在通常都是图片加载框架来完成,类似Glide.Picasso,Fresco等,他们可以帮助你减少工作量, 内存问题还是存在

再来分析一下解码格式:

这个跟缩放比例效果差不多, 只是同样的分辨率的图片加载到内存中时占用内存减少了

比如ARGB_8888 共32位

RGB_565  共16位

ARGB_4444 共16位

很明显这样格式图片加载的内存情况是ARGB_8888是其他格式的两倍内存

另外的问题是ARGB_8888看起来很清晰的, 其它的看起来图片有种糊了的感觉,自己选择吧

结论, 降低内存占用非常有效

最后一个是局部加载, 并没有怎么使用到,也不清楚就不说了

最后还有一个方法避免OOM, 开启largeHeap属性, 但是但是, 以前我们开启这个属性后被Oppo应用市场认定为占用内存过高, 不建议用户安装......所以我们又取消了!

总的来说, Bitmap在内存是变现的是不可控, 我项目OOM问题一直没有得到有效解决,因为图片编辑视频编辑之类的功能占用内存过高,继续使用OOM是必然的, 跟IOS的同学交流了一番,他们说IOS的应用内存可以占用到1个G以上, 轻松跑到500M是没问题的, IOS的内存机制可以持续给内存使用, 具体我也不清楚,并且他们可以手动释放内存?malloc, free这样子?

如果大家有比较好的方案,还望留言交流互相帮助 [笑脸.gif]

补充: Android8.0开始Bitmap数据内存存在native层, 单个应用可用的内存显着增长, 极大的降低了OOM的概率(2018年3月22日)

Ⅲ Android 图片加载(一)高效加载Bitmap 基础篇

由于Bitmap的特殊性以及Android对单个应用所规定的最大内存限制,我们在同时加载大量Bitmap时很容易发生内存溢出,即我们通常所说的OutOfMemoryError(OOM),因此高效加载Bitmap就成为了每个Android开发者的必备技能。

在学习如何高效地加载Bitmap之前,首先介绍一下如何加载一个Bitmap。我们都知道,Bitmap在Android中通常指的是一张图片,那么如何将JPG、PNG等格式的图片转换成Bitmap对象呢?BitmapFactory类给我们提供了一些方法:

接下来开始介绍如何高效地加载Bitmap,其实核心思想很简单: 就是采用BitmapFactory.Options参数来调整图片尺寸来适配控件的大小。

假如我们显示图片的控件ImageView宽高为100×100像素,而图片的尺寸为1024×1024像素,这个时候如果将整个图片加载进来并显示到控件上,自然是很占用内存资源的。这个时候可以通过BitmapFactory.Options按一定的采样率加载缩小后的图片,再将缩小后的图片显示到ImageView中,这样就能减小内存占用从而在一定程度上避免OOM的发生。

通过BitmapFactory.Options来缩放图片,主要是使用它的inSampleSize参数,也就是前面提到的采样率。当采样率inSampleSize为1时,采样后的图片大小为原图大小;当采样率inSampleSize>1,比如为2时,采样后的图片宽高都为原图的1/2,即像素降为原图的1/4,占用的内存大小也就是原图的1/4;比较特殊的是,当采样率inSampleSize<1时,系统会自动将该值当做1来处理。 因此可以得出一个结论:采样率inSampleSize必须是大于1的整数图片才会有缩小的效果,并且采样率同时作用于宽高,也就是说采样后的图片会缩小到原图的1/(inSampleSize^2)。比如inSampleSize=4,那么缩放比例为1/16。

我们现在知道了,通过采样率可以提高图片的加载效率,那么如何才能计算出最合适的采样率?我们可以按照如下流程:

接下来以decodeFile方法为例实现图片的缩放,其他三个方法处理方式类似。

下一篇: Android 图片加载(二)图片加载框架Glide 入门篇

《Android开发艺术探索》

Ⅳ android 读取Bitmap的几种方式

想读取本地项目里的资源图片,但又不能用到R文件。查了很多资料终于找到了。 现总结以下几种读取Bitmap的方法。 1.以文件流的方式,假设在sdcard下有 test.png图片 FileInputStream fis = new FileInputStream("/sdcard/test.png"); Bitmap bitmap=BitmapFactory.decodeStream(fis); 2. 以R文件的方式,假设 res/drawable下有 test.jpg文件Bitmapbitmap =BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.test); 3.以ResourceStream的方式,但不用到R文件。 Bitmap.bitmap=BitmapFactory.decodeStream(getClass().getResourceAsStream(“/res/drawable/test.png”)); 图片名就可以读取到 Bitmap啦。 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; //图片宽高都为原来的二分之一,即图片为原来的四分一 //以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。

热点内容
滑板鞋脚本视频 发布:2025-02-02 09:48:54 浏览:432
群晖怎么玩安卓模拟器 发布:2025-02-02 09:45:23 浏览:557
三星安卓12彩蛋怎么玩 发布:2025-02-02 09:44:39 浏览:743
电脑显示连接服务器错误 发布:2025-02-02 09:24:10 浏览:537
瑞芯微开发板编译 发布:2025-02-02 09:22:54 浏览:146
linux虚拟机用gcc编译时显示错误 发布:2025-02-02 09:14:01 浏览:232
java驼峰 发布:2025-02-02 09:13:26 浏览:651
魔兽脚本怎么用 发布:2025-02-02 09:10:28 浏览:532
linuxadobe 发布:2025-02-02 09:09:43 浏览:212
sql2000数据库连接 发布:2025-02-02 09:09:43 浏览:726