你不知道的Bitmap
Bitmap在Android中广泛应用,尤其是图片处理时。看下今天Agenda:
位图的基本概念
Bitmap与文件格式
Bitmap内存占用优化
BitmapShader的应用
recycle的实践
我们先抛开Bitmap在Android上的实现不谈,先看看Bitmap在物理世界的具体含义
位图是什么?
计算机图形学上的概念
根据位深度,可将位图分为1、4、8、16、24及32位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。例如,位深度为1的像素位图只有两个可能的值(黑色和白色),所以又称为二值位图。位深度为8的图像有28(即256)个可能的值。位深度为8的灰度模式图像有256个可能的灰色值。
位图的反面:矢量图
移动端开发中矢量图的应用很少,对于区块信息,因为很少遇到这种需要无限缩放的场景。对于少数有缩放需要的场景,shape以及Bitmap类提供的(九点图)功能已经可以满足绝大多数场景。
Bitmap颜色格式
每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大,Android定义了这样几种图片格式。
4444已经被废弃,因为显示质量不好。
8888是Bitmap默认的颜色配置信息,也是最占空间的一种配置。
565 如果不需要 alpha 通道,特别是资源本身为 jpg 格式的情况下,用这个格式比较理想
Skia是一个开源的二维图形库,提供各种常用的API,并可在多种软硬件平台上运行。谷歌Chrome浏览器、Chrome OS、安卓、火狐浏览器、火狐操作系统以及其它许多产品都使用它作为图形引擎。
Bitmap占用内存大小计算
已知Bitmap模式为ARGB_8888,假设这张图最后加载成一个300 * 300 的Bitmap ,那么 内存中的大小应该是?
位图文件格式
一个比较典型的压缩算法
位图的格式选择
Bitmap.CompressFormat.JPEG:表示以JPEG压缩算法进行图像压缩,压缩后的格式可以是“.jpg”或者“.jpeg”,是一种有损压缩。
JPEG是最普遍在万维网用来储存和传输照片的格式。
Bitmap.CompressFormat.PNG:表示以PNG压缩算法进行图像压缩,压缩后的格式可以是“.png”,是一种无损压缩。这意味着在生成文件时,可能会忽略掉 质量。
和刚才的Bitmap.Config相比,这个内部类只会在压缩文件等时被用到
Bitmap.CompressFormat.WEBP 2010年谷歌推迟的图片格式,专门用来在web中使用; 第一个版本的webp图片格式是有损的, 新版本中webp图片是无损的。
它的压缩率是三者中最高的。
WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.
Lossless WebP supports transparency (also known as alpha channel) at a cost of just 22% additional bytes. For cases when lossy RGB compression is acceptable, lossy WebP also supports transparency, typically providing 3× smaller file sizes compared to PNG.
从文件生成Bitmap
让我们首先了解一下Bitmap从文件生成的流程。
首先说Bitmap是一个final类,因此不能被继承。Bitmap只有一个构造方法,且该构造方法是没有任何访问权限修饰符修饰,也就是说该构造方法是friendly,但是谷歌称Bitmap的构造方法是private(私有的),感觉有点不严谨。不管怎样,一般情况下,我们不能通过构造方法直接新建一个Bitmap对象。从文件创建Bitmap类就离不开BitmapFactory
BitmapFactory类提供了四类方法:decodeFile、decodeRe-source、decodeStream和decodeByteArray,分别用于支持从文件系统、资源、输入流以及字节数组中加载出一个Bitmap对象,其中decodeFile和decodeResource又间接调用了decode-Stream方法,这四类方法最终是在Android的底层实现的,对应着BitmapFactory类的几个native方法。
其实核心思想也很简单,那就是采用BitmapFactory.Options来加载所需尺寸的图片。通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片大小为图片的原始大小;当inSampleSize大于1时,比如为2,那么采样后的图片其宽/高均为原图大小的1/2,而像素数为原图的1/4,其占有的内存大小也为原图的1/4。
优化Bitmap占用
获取到占用空间尽可能小
缩放图片,主要是用到了它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片大小为图片的原始大小;当inSampleSize大于1时,比如为2,那么采样后的图片其宽/高均为原图大小的1/2,而像素数为原图的1/4,其占有的内存大小也为原图的1/4。
降低图片采样率
(1)将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。 这一步并不会读取文件的像素区块。只会去从
(2)从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth和outHeight参数。
(3)根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize。
(4)将BitmapFactory.Options的inJustDecodeBounds参数设为false,然后重新加载图片。
先缩小后处理,如需要对图片做高斯模糊
(我们现在有个需求,要求将一张图片进行模糊,然后作为 ImageView 的 src 呈现给用户,而我们的原始图片大小为 1080*1920,如果我们直接拿来模糊的话,一方面模糊的过程费时费力,另一方面生成的图片又占用内存,实际上在模糊运算过程中可能会存在输入和输出并存的情况,此时内存将会有一个短暂的峰值。
Bitmap与BitmapShader
对于Bitmap而言,从文件中读取出来,工作还远未结束。Bitmap的应用在很多时候都是用来构建一个BitmapDrawable,然后再去设置给别人做背景。
要不要用recycle
当然这只是其中一种的gc触发路径。在别的很多情况下都有可能,但是recycler并不会触发gc,或者说recycler方法并不能在性能上带来提升。gc的事情还是去交给gc去做吧。
你不知道的Bitmap相关推荐
- 你不知道的BAT大数据面试题
你不知道的BAT大数据面试题 1.kafka的message包括哪些信息 一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成 header部分由一个字 ...
- Android 自定义View Canvas —— Bitmap
Bitmap 绘制图片 常用的方法有一下几种 (1) drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint ...
- BitMap 内存使用优化
在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图 ...
- 第52章,bitmap图像处理(从零开始学android),第52章、Bitmap图像处理(从零开始学Android)...
1.Drawable → Bitmap public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitma ...
- python3.9.0 print_关于 Python 3.9,那些你不知道的事
原标题:关于 Python 3.9,那些你不知道的事 作者 | Ayushi Rawat 编译 | 高卫华 题图 | 视觉中国 Python一直在满足社区需求,并且将成为未来使用最多的语言. Pyth ...
- GDI+ Bitmap与WPF BitmapImage的相互转换
原文:GDI+ Bitmap与WPF BitmapImage的相互转换 using System.Windows.Interop; //... // Convert BitmapImage to Bi ...
- Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...
1.java.lang.Math类常用的常量和方法: Math.PI 记录的圆周率 Math.E 记录e的常量 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 ...
- C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。...
原文:C#图片灰度处理(位深度24→位深度8) #region 灰度处理/// <summary>/// 将源图像灰度化,并转化为8位灰度图像./// </summary>// ...
- 对象----《你不知道的JS》
最近在拜读<你不知道的js>,而此篇是对于<你不知道的js>中对象部分的笔记整理,希望能有效的梳理,并且深入理解对象 一.语法 对象两种定义形式:声明(文字)形式.构造形式 声 ...
- R.drawable 转 bitmap
引用:http://zhidao.baidu.com/question/291703800.html Bitmap bmp=BitmapFactory.decodeResource(r, R.draw ...
最新文章
- 关于window.localtion的用法几点总结
- JVM---堆(对象分配过程)
- IOS4.x下UIWebView的显示问题
- python 微信爬虫_python3简单实现微信爬虫
- DELETE大批量数据的性能优化
- 通过命令行界面使用AWS ElasticMapReduce
- c语言八个方向迷宫课程设计,【精品资料最新版】C语言课程设计-迷宫游戏.doc...
- PHP 递增/递减运算符
- C语言中的static
- 【Oracle】三种方式查看SQL语句的执行计划
- 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具
- python模块之httplib(在py3中功能进一步强大,请详看文档)
- M1 版 MacBook SSD 为何会损耗巨大?
- QTTabBar+Office Tab+Quicker 助力高效使用Windows办公
- 春节假期最值得阅读的10本书
- PHP Yar - 学习/实践
- 如何提升Excel水平?5个Excel常用技巧,学会不加班
- Bandizip6.27百度网盘
- 在线网校教育平台的开发,题库的搭建必不可少
- 程序集定义(Assembly Definition File)