| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android Bitmap 研究与思考? -> 正文阅读 |
|
[移动开发]Android Bitmap 研究与思考? |
一:Bitmap 是什么?从字面的意思上可以理解为 位图 。 在Android中是一种存储像素的数据结构,通过这个对象可以得到一系列的图像属性。还可以对图像进行旋转,切割,放大,缩小等操作。 我画了一张像素图,大家理解一下。 我们一般说说的手机分辨率 1080 * 1920 , 就代表手机屏幕横向是 1080 个像素点,竖向是 1920 个像素点,整个手机的像素点是两者相乘为 2073600 个像素点。 从代码上来讲 ,Bitmap 是一个 final 类,实现了 Parcelable 接口,因此不能被继承。Bitmap只有一个构造方法,且该构造方法是私有的,所以无法通过 new 的方式来建一个 Bitmap。 在 Android 中,bitmap 只是一个存储像素信息的对象,是内存虚构出来的。 二:bitmap 到底占用多少内存?首先我们先来看看怎么创建一个 bitmap ,上面我们已经提到过,无法通过 new 的方式创建Bitmap 对象 。 幸运的是 Bitmap 提供了多个静态方法。 可以看到除了createBitmap(Bitmap src) 和 createBitmap( Picture source) 这两个方法外,其他的方法都是需要一个 Config 参数。 Bitmap.Config google官方描述为: Possible bitmap configurations. A bitmap configuration describes how pixels are stored. This affects the quality (color depth) as well as the ability to display transparent/translucent colors. Bitmap.Config 描述了像素的存储方式,这会影响质量(颜色深度)以及显示透明/半透明颜色的能力。在Bitmap.Config文档中我们看到四个枚举变量。
说白了就是:这种模式每个像素只存储一个透明度值,不会存储其他颜色信息。所以我们在创建蒙版的时候,推荐使用这种模式。每个像素占 8 位,也就是 1 个字节。
即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 , 也就是每个像素占 2 个字节。
即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位, 也就是一个像素占 4 个字节。
即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位, 也就是一个像素占 2 个字节。 内存计算我们知道了,每种模式下,每个像素所占用的内存,就能很清楚的算清楚,每个bitmap 所占用的内存。比如:
我们创建了一个 bitmap ,宽 1024 个像素,高 1024 个像素,模式 ARGB_8888 。所以我们很容易算出:
最后算出这个bigmap 占用内存为 4 M 。 总结:
三:Bitmap 尺寸怎么算?在第二部分,我们知道了 bitmap 占用的内存 = bitmap 总像素个数 x 单个像素占用的内存。 其中,单个像素占用的内存由存储模式决定,比如 Config.ARGB_8888 。 现在我们要弄清楚 bitmap 尺寸怎么计算? 首先上一段代码,计算ImageView中加载图片的具体尺寸和内存占用大小。
实验1:我们做个试验,现在布局中定义个 ImageView , 尺寸是 100 dp x 100 dp
给 imageView 设置一个图片,名字是 image.png , 尺寸是 300 x 300 。
然后输出 bitmap 宽高和占用内存。
在 红米4 手机上输出:
在我的杂牌手机上输出:
至此,我们可以得出结论:
查阅 ImageView 源码,发现 ImageView中图片是以 Bitmap 形式保存在内存中;查阅 Bitmap 源码,发现图像在内存中的实际 bitmap 尺寸和图像的原始尺寸(withPixel * heightPixel),资源文件像素密度(sourcedensity)以及目标手机的像素密度(targetDensity)有密不可分的关系。 其中 sourceDensity>>1 部分是为了对 targetDensity/sourceDensity 进行四舍五入 综上,
实验2测试方案:将尺寸为图片A(尺寸60*60 大小2.02K)放入drawable和drawable-xxhdpi文件夹,图片显示尺寸采用wrap_content,分别用mate 9手机进行测试; 测试结果:内存占用分别为129600Byte和14400Byte,图片在ImageView中的bitmap尺寸为180 * 180和 60 * 60; 结果分析:相同的图片放在不同的 drawable 目录下,bitmap 宽高不一样,bitmap 占用的内存也不一样。内存占用与图片的原始尺寸没有关系,与 bitmap尺寸有密切的关系。 实验3测试方案:将尺寸为图片A(尺寸60 x 60 ,大小2.02K)放入drawable-xxhdpi文件夹,图片显示尺寸设置为30dp * 30dp和 60dp * 60dp,分别用mate 9手机进行测试; 测试结果:内存占用均为14400Byte,bitmap尺寸均为60*60; 结果分析:说明内存占用与图片的实际显示尺寸没有关系。 实验4测试方案:将尺寸为图片A(尺寸 60 x 60 大小 2.02K ),图片B(尺寸 60 x 60 ,大小1.63K),将图片均放入drawable-xxhdpi文件夹,图片显示尺寸采用wrap_content,用华为mate 9(xxhdpi)手机进行测试; 测试结果:二者内存占用均为14400Byte,bitmap尺寸为 60 x 60; 结果分析:说明内存占用单独与图片原始大小没有关系。 四:什么是 DPI ?先放一个维基百科 链接 DPI DPI(英语:Dots Per Inch,每英寸点数)是一个量度单位,用于点阵数字图像,意思是指每一英寸长度中,取样或可显示或输出点的数目。如:打印机输出可达600DPI的分辨率,表示打印机可以在每一平方英寸的面积中可以输出600X600=360000个输出点。 打印机所设置之分辨率的DPI值越高,印出的图像会越精细。打印机通常可以调校分辨率。例如撞针打印机,分辨率通常是60至90 DPI。喷墨打印机则可达1200 DPI,甚至9600 DPI。激光打印机则有600至1200 DPI。 一般显示器为96 DPI,印刷所需位图的DPI数则视印刷网线数而定。一般150线印刷质量需要350 DPI的位图。而这里的D(dot)就是像素(pixel)。 五:什么是 PPI ?每英寸像素(英语:Pixels Per Inch,缩写:PPI),又被称为像素密度,是一个表示打印图像或显示器单位面积上像素数量的指数。一般用来计量电脑显示器,电视机和手持电子设备屏幕的精细程度。通常情况下,每英寸像素值越高,屏幕能显示的图像也越精细。 电脑与手机屏幕的每英寸像素值取决于尺寸和分辨率,通常指的就是每英寸上的像素点数。同样的一台显示器,如果分辨率设置的不同,像素点数也不同。分辨率越高,每英寸像素值也越高。 六:Android 系统 DPI 分级根据屏幕每英寸像素值的不同,Android系统的开发者将平板电脑和手机的屏幕分成五类: 随着屏幕技术的发展,出现了比 xxhdpi 更高密度的屏幕 xxxhdpi 七:不同密度下的图片内存占用怎么计算往下阅读前,可以首先阅读 郭霖的博客: 在郭神的文章中,讨论了图片放在不同的 dpi 目录下,ImageView 会被缩放,ImageView 的宽高会改变。但是文章中没有谈论的是 ImageView 宽高改变了,ImageView 中的 bitmap 宽高会不会改变,因为 bitmap 的宽高会直接影响到所占用内存的大小。 我们先来做个实验,首先计算出当前手机屏幕密度,计算方法是:
计算的结果是 480 ,可以看出来,我的手机屏幕密是 超高像素密度 , 对应的是 xxhdpi 我现在有一张图片 image.png,尺寸是300 x 300 。 条件:ImageView 的宽高是 wrap_content
实验1:把图片放在 xxhdpi获取 bitmap 的宽高和占用内存
图片放在 xxhdpi , 屏幕上显示的是原图的大小,原来的尺寸是多少,在屏幕上就会显示多少。获取的 bitmap 宽高也是原图的宽高,尺寸没有发生变化,所占内存也没有变化 实验2:把图片放在 xhdpi获取 bitmap 的宽高和占用内存
图片放在 xhdpi 获取的 bitmap 宽高 和 xxhdpi 一样 ,内存占用也一样。 实验3:把图片放在 hdpi获取 bitmap 的宽高和占用内存
图片放在 hdpi 获取的 bitmap 宽高 和 xxhdpi 、 xhdpi 一样 ,内存占用也一样。 实验4:把图片放在 xxxhdpi
图片放在 xxxhdpi 获取的 bitmap 宽高都比原图要小,占用内存也小了。小了多少是怎么计算的。 bitmap宽度 = (手机屏幕密度 / 图片所在目录像素密度) * 原图宽度 结合到本例就是:
同理,bitmap 的高度也是这样计算的。 那么问题来了,为什么放在 xxxhdpi 目录下,bitmap 的尺寸发生了变化,而放在 hdpi 、xhdpi bitmap 的尺寸却没有发生变化 ??? 其实像Android 框架方面知识点还有很多,由于文章篇幅长度限制,就不在下面一一概述了。为了帮助大家掌握好 Android 方面的所有框架知识点,特此准备了一份《Android 百大框架》学习指南,有需要的可以 点击直接参考↓↓↓
|
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 | -2025/3/10 9:45:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |