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相关推荐

  1. 你不知道的BAT大数据面试题

          你不知道的BAT大数据面试题 1.kafka的message包括哪些信息 一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成 header部分由一个字 ...

  2. Android 自定义View Canvas —— Bitmap

    Bitmap 绘制图片 常用的方法有一下几种 (1) drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint ...

  3. BitMap 内存使用优化

    在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图 ...

  4. 第52章,bitmap图像处理(从零开始学android),第52章、Bitmap图像处理(从零开始学Android)...

    1.Drawable → Bitmap public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitma ...

  5. python3.9.0 print_关于 Python 3.9,那些你不知道的事

    原标题:关于 Python 3.9,那些你不知道的事 作者 | Ayushi Rawat 编译 | 高卫华 题图 | 视觉中国 Python一直在满足社区需求,并且将成为未来使用最多的语言. Pyth ...

  6. GDI+ Bitmap与WPF BitmapImage的相互转换

    原文:GDI+ Bitmap与WPF BitmapImage的相互转换 using System.Windows.Interop; //... // Convert BitmapImage to Bi ...

  7. Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...

    1.java.lang.Math类常用的常量和方法: Math.PI 记录的圆周率 Math.E 记录e的常量 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 ...

  8. C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。...

    原文:C#图片灰度处理(位深度24→位深度8) #region 灰度处理/// <summary>/// 将源图像灰度化,并转化为8位灰度图像./// </summary>// ...

  9. 对象----《你不知道的JS》

    最近在拜读<你不知道的js>,而此篇是对于<你不知道的js>中对象部分的笔记整理,希望能有效的梳理,并且深入理解对象 一.语法 对象两种定义形式:声明(文字)形式.构造形式 声 ...

  10. R.drawable 转 bitmap

    引用:http://zhidao.baidu.com/question/291703800.html Bitmap bmp=BitmapFactory.decodeResource(r, R.draw ...

最新文章

  1. 关于window.localtion的用法几点总结
  2. JVM---堆(对象分配过程)
  3. IOS4.x下UIWebView的显示问题
  4. python 微信爬虫_python3简单实现微信爬虫
  5. DELETE大批量数据的性能优化
  6. 通过命令行界面使用AWS ElasticMapReduce
  7. c语言八个方向迷宫课程设计,【精品资料最新版】C语言课程设计-迷宫游戏.doc...
  8. PHP 递增/递减运算符
  9. C语言中的static
  10. 【Oracle】三种方式查看SQL语句的执行计划
  11. 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具
  12. python模块之httplib(在py3中功能进一步强大,请详看文档)
  13. M1 版 MacBook SSD 为何会损耗巨大?
  14. QTTabBar+Office Tab+Quicker 助力高效使用Windows办公
  15. 春节假期最值得阅读的10本书
  16. PHP Yar - 学习/实践
  17. 如何提升Excel水平?5个Excel常用技巧,学会不加班
  18. Bandizip6.27百度网盘
  19. 在线网校教育平台的开发,题库的搭建必不可少
  20. 程序集定义(Assembly Definition File)

热门文章

  1. 使用JDBC+JSP分层实现新闻管理系统注册、登录功能
  2. 随手记_unbuntu从命令行进入图形界面
  3. caffe调参经验资料文章
  4. 读《学术研究,你的成功之道》读书笔记分享给各位
  5. 论文阅读笔记(二)——Xception
  6. scrapy数据存储在mysql数据库的两种方式
  7. 添加SAP_ALL权限
  8. amazeui学习笔记--css(常用组件2)--面包屑导航Breadcrumb
  9. 手动安装MySQL8.0
  10. OSGi中的ServletContext