android的图片的初步学习理解
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的图片的初步学习理解的更多相关文章
- 41.Android之图片放大缩小学习
生活中经常会用到图片放大和缩小,今天简单学习下. 思路:1.添加一个操作图片放大和缩小类; 2. 布局文件中引用这个自定义控件; 3. 主Activity一些修改. 代码如下: 增加图片操作类: ...
- Android NDK开发及OpenCV初步学习笔记
https://www.jianshu.com/p/c29bb20908da Android NDK开发及OpenCV初步学习笔记 Super_圣代 关注 2017.08.19 00:55* 字数 6 ...
- android的helloworld工程目录学习
android的helloworld工程目录学习 Android工程的主要目录有src.gen.Android X.X.bin.res等文件夹. 1. Src文件夹 Src文件夹包含java源 ...
- [深入理解Android卷一全文-第八章]深入理解Surface系统
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版.而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...
- [深入理解Android卷一全文-第十章]深入理解MediaScanner
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断.所以我将在CSDN博客中全文转发这两本书的全部内容. ...
- Android 多媒体视频播放一( 多媒体理解与经验分享)
前言 说到android的多媒体,一把辛酸一把泪,当初听说会多媒体的比较牛掰,公司也有需求,于是乎我也积极的加入研究android多媒体的行列,记得以前刚接触的时候,最开始还是比较头大的,主要是但是很 ...
- 谈谈Android 6.0运行时权限理解
前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...
- 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析
原文:关于Android中图片大小.内存占用与drawable文件夹关系的研究与分析 相关: Android drawable微技巧,你所不知道的drawable的那些细节 经常会有朋友问我这个问题: ...
- Android高手进阶:Adapter深入理解与优化
一般是针对包含多个元素的View,如ListView,GridView,ExpandableListview,的时候我们是给其设置一个Adapter.Adapter是与View之间提供数据的桥梁,也是 ...
随机推荐
- hdoj 1003 学习思路
基本解题思路:动态规划,不考虑穷举,分治. 根据网上,状态转移方程是:MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]} 翻译公式:到当前位置i 时,最大子序列和为: ...
- Spark读取配置(转)
转自:https://github.com/keepsimplefocus/spark-sourcecodes-analysis/blob/master/markdowns/Spark%E8%AF%B ...
- Java IO流学习总结五:转换流-InputStreamReader、OutputStreamWriter
类的继承关系 Reader |__ BufferedReader.StringReader.InputStreamReader |__ FileReader Writer |__ BufferedWr ...
- Object-c 调用unity的 UIViewController和UnitySendMessage
.mm文件中实现 #import <UIKit/UIKit.h> extern UIViewController *UnityGetGLViewController(); extern & ...
- avalon2学习教程05属性操作
avalon2与avalon1的属性操作虽然都是使用ms-attr,但用法完全不一样. avalon1是这样操作属性的 其语法为 ms-attr-valueName="vmProp" ...
- mysql 5.7.3.0-m13安装教程
安装mysql百度经验地址:(默认安装,除了选择不更新和选择保存路径,其它基本是下一步下一步) http://jingyan.baidu.com/article/7e440953d6f0702fc1e ...
- InvalidArgumentError (see above for traceback): Assign requires shapes of both tensors to match. lhs shape= [2048,38] rhs shape= [2048,2]
做tensorflow object detection 中,清空下checkpoint就可以啦
- 详解MySQL数据表类型
学习Mysql数据库,Mysql表类型都有哪些是一定需要知道的,下面就为您介绍七种Mysql表类型,希望能对您学习Mysql表类型有所帮助. MySQL作为当前最为流行的免费数据库服务引擎,已经风靡了 ...
- 前端路由两种模式:hash、history
随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...
- 支付宝支付Java代码
支付宝调用流程 开发前的准备工作 配置应用网关 应用网关里面填写的值就是商户后台的异步回调地址.也就是在支付宝付完款之后,由支付宝调用商户,便于商户验证订单各信息和更新订单状态 授权回调地址 授权回调 ...