Android支持JPEG和PNG格式、GIF和BMP格式图片的支持。

图片最终要显示在屏幕上,都会对应一个屏幕上的点,即对应一个颜色值。不同格式的图片,只是不同压缩编码和解压算法。

也就是说,我们看到的.jpg、.png图片的文件大小只有几十KB,担把它们加载到内存中时,每张图片最终都按长X宽展开,计算其占用内存大小的就变成了(ARGB_8888格式的图片,每像素占用 4 Byte,而 RGB565则是 2 Byte,假设是ARGB_8888):

内存占用=长 X 宽 X 4bytes

这种算法其这还忽略屏幕的Density,如我们上Day 21的面试题中也提到过的,放在不同的drawable目录中的图片显示时会根据Denisty有一定的缩放。所以有时候图片占用的内存会比我们上面公式计算出来的还要大很多。

Bitmap和Drawable

Bitmap是Android系统中的图像处理的最重要类。可以简单地说,Bitmap代表的是图片资源在内存中的数据结构,如它的像素数据,长宽等属性都存放在Bitmap对象中。Bitmap类的构造函数是私有的,只能是通过JNI实例化,系统提供BitmapFactory工厂类给我们从从File、Stream和byte[]创建Bitmap的方式。

Drawable官文文档说明为可绘制物件的一般抽象。View也是可以绘制的,但Drawable与View不同,Drawable不接受事件,无法与用户进行交互。我们知道很多UI控件都提供设置Drawable的接口,如ImageView可以通过setImageDrawable(Drawable drawable)设置它的显示,这个drawable可以是来自Bitmap的BitmapDrawable,也可以是其他的如ShapeDrawable。

也就是Drawable是一种抽像,最终实现的方式可以是绘制Bitmap的数据或者图形、Color数据等。理解了这些,你很容易明白为什么我们有时候需要进行两者之间的转换。

优化手段

在Android 3.0之前的版本,Bitmap像素数据存放在Native内存中,而且Nativie内存的释放是不确定的,容易内存溢出而Crash,所以一般我们不使用的图片要调用recycle()。

 
 

从3.0开始,Bitmap像素数据和Bitmap对象一起存放在Dalvik堆内存中(中从源代码上看是多了一个byte[] buffer用来存放数据),也就是我们常说的Java Heap内存。

 
 

除了这点改变之外,3.0版本的还增加了一个inBitmap属性(BitmapFactory.Options.inBitmap)。如果设置了这个属性则会重用这个Bitmap的内存从而提升性能。但是这个重用是有条件的,在Android4.4之前只能重用相同大小的Bitmap,Android4.4+则只要比重用Bitmap小即可。

当然优化的手段还有很多,比如使用采样率(inSampleSize),如果最终要压缩图片,如显示缩列图,我们并不需要加载完整的图片数据,只需要按一定的比例加载即可;使用Matrix变形等,比如使用Matrix进行放大,虽然图像大了,但并没有占用更多的内存。

使用第三方图片库也是一种优化吧,它们帮我们完成了很多工作。Facebook的Fresco还自己开辟了Native内存用于存储图片,以得到更大的内存空间(其实我还不确认这种方式是否有兼容性问题)。

要加载很大的图片怎么办?

如果图片很大,比如他们的占用内存算下来就直接OOM了,那么我们肯定不能直接加载它。解决主法还是有很多的,系统也给我们提供了一个类BitmapRegionDecoder,可以用来分块加载图片。

小结

虽然网上有很多开源的和图片相关的库,但我们还是有必要了解一下Bitmap的相关的知识的,有时候我们只需要一个简单的功能,可以手动自己实现,不一定非要加进一个开源库。代码越是简单,可控性和可维护性越好,对吧。

 
 

作者:goeasyway
链接:https://www.jianshu.com/p/3c597baa39e5
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

android的图片的初步学习理解的更多相关文章

  1. 41.Android之图片放大缩小学习

    生活中经常会用到图片放大和缩小,今天简单学习下. 思路:1.添加一个操作图片放大和缩小类;  2. 布局文件中引用这个自定义控件;  3. 主Activity一些修改. 代码如下: 增加图片操作类: ...

  2. Android NDK开发及OpenCV初步学习笔记

    https://www.jianshu.com/p/c29bb20908da Android NDK开发及OpenCV初步学习笔记 Super_圣代 关注 2017.08.19 00:55* 字数 6 ...

  3. android的helloworld工程目录学习

    android的helloworld工程目录学习 Android工程的主要目录有src.gen.Android X.X.bin.res等文件夹. 1.     Src文件夹 Src文件夹包含java源 ...

  4. [深入理解Android卷一全文-第八章]深入理解Surface系统

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版.而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...

  5. [深入理解Android卷一全文-第十章]深入理解MediaScanner

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断.所以我将在CSDN博客中全文转发这两本书的全部内容. ...

  6. Android 多媒体视频播放一( 多媒体理解与经验分享)

    前言 说到android的多媒体,一把辛酸一把泪,当初听说会多媒体的比较牛掰,公司也有需求,于是乎我也积极的加入研究android多媒体的行列,记得以前刚接触的时候,最开始还是比较头大的,主要是但是很 ...

  7. 谈谈Android 6.0运行时权限理解

    前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...

  8. 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

    原文:关于Android中图片大小.内存占用与drawable文件夹关系的研究与分析 相关: Android drawable微技巧,你所不知道的drawable的那些细节 经常会有朋友问我这个问题: ...

  9. Android高手进阶:Adapter深入理解与优化

    一般是针对包含多个元素的View,如ListView,GridView,ExpandableListview,的时候我们是给其设置一个Adapter.Adapter是与View之间提供数据的桥梁,也是 ...

随机推荐

  1. 向SqlParameter内动态添加参数

    动态向SqlParameter 里添加相应参数,方法如下 先定义一个List,然后再往List里面添加SqlParameter对象,然后将List转为SqlParameter数组即可 List< ...

  2. kafka config

    Config parameters that influence the log retention time. log.roll.hours  # how long to produce a new ...

  3. es6初级之解构----之二 及 键值反转实现

    1.解构: 不定参数,扩展表达式 let arr = [100, 201, 303, 911]; let [one, ...others] = arr; console.log(others.leng ...

  4. 尚硅谷redis学习1-NOSQL简介2

    NoSql数据模型简介 聚合模型:KV键值,BSON 列族: 图形,这里的图形不是指真正的图形,而是关系图 NoSql数据库的四大分类 KV键值:BerkeleyDB,Redis,tair,memca ...

  5. 初级java程序员-各公司技能要求

    熟悉tomcat部署和性能调试,开发常用linux 命令,有性能调优(tomcat,sql等)经验优先: 熟练使用SSH.springmvc.mybatis.Hibernate.jquery等框架,了 ...

  6. VS2017断点调试UNITY2018.3 经常卡住的问题

    发现了VS下断点经常导致unity卡住的原因,是vs占用CPU太高导致的,这其中又是vs service hub 造成的,这个除了在代码中提示各函数引用之外好像没什么用,我定位到它的安装目录,删除了配 ...

  7. TypeScript语言学习笔记(2)

    接口 // 在参数类型中定义约束 function printLabel(labelledObj: { label: string }) { console.log(labelledObj.label ...

  8. linux编译安装php apache mysql (已试过)

    阅读目录 (全部使用源码安装方式,先安装mysql,然后是apache,再是php,这样好像能防止挺多问题的,期间出现问题基本是依赖没有或者版本不对) 1.简介 2.安装apache 2.1.yum方 ...

  9. centos6安装自带php

    一.Centos 6安装自带PHP CentOS 默认仓库中包含了php套件,我们可以直接使用yum安装.下面是最小化安装,我们使用php-fpm来解析php. yum install -y php- ...

  10. contextlib 上下文管理器

    在Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们.正确关闭文件资源的一个方法是使用try...finally: try: f = open('/path/to/file', ...