android图片适配(图片大小与屏幕密度)Bitmap占用内存计算

本文深入探讨Android系统中图片的dpi计算、dp与px转换、资源目录匹配规则,以及ImageView和Bitmap的尺寸计算和内存占用。通过实例分析不同手机型号和dpi下,同一图片在不同目录下的显示效果和内存消耗,总结了Android项目中图片适配的流程和关键点。
摘要由CSDN通过智能技术生成

目录

概述

dpi 计算公式

dp与px换算公式:

android系统适配图片规律:

同名图片放在不同密度的文件夹下,系统选择图片规律

同一张图片,放在不同密度的Drawable文件夹下,ImageView设置src,宽高为warp_content,ImageView被加载出来的实际尺寸的规律

实际加载的UI情况如下:

不同dpi的手机,同一张图片,放在不同密度的Drawable文件夹下,ImageView被加载后,ImageView尺寸和Bitmap尺寸。

ImageView尺寸计算规律:

Bitmap占用内存计算

Bitmap占用内存大小计算公式

Bitmap占用内存实测


概述

android项目中图片适配流程。

屏幕密度:单位英寸面积上的像素点数,与分辨率是两个不同的概念。

获取屏幕密度

方法一:adb 命令

adb shell wm density

方法二:api调用

resource.getDisplayMetrics().densityDpi

ldpi: 屏幕密度为120的手机设备

mdpi: 屏幕密度为160的手机设备(此为baseline,其他均以此为基准,在此设备上,1dp = 1px)   

hdpi: 屏幕密度为240的手机设备   1.5

xhdpi: 屏幕密度为320的手机设备  2

xxhdpi:屏幕密度为480的手机设备  3

xxxhdpi:屏幕密度为640的手机设备  4

dpi 计算公式

dpi  = (屏幕宽度像素的平方  + 屏幕高度像素的平方  )开根号 / 物理尺寸(英寸) =  斜对角的像素值 / 斜对角的物理尺寸(英寸)

dp与px换算公式:

1dp = dpi / 160  px

例:华为p30, dpi = 480,  1dp = 480 /160 px = 3px.

android系统适配图片规律:

同名图片放在不同密度的文件夹下,系统选择图片规律

android终端会根据自己的dpi值,会匹配与之最相近密度的资源目录,如果没有找到,则会向更高资源目录寻找,再向无关屏屏幕密度的文件夹nodpi寻找, 找不到再向低一级的屏幕密度的目录下寻找,如果还是找不到就要匹配drawable目录下了,此时drawable-v24 v21等目录的优先级高于drawable, 最后向 ldpi匹配。

dpi为480的手机,它对应的是xxhdpi目录。它的匹配规律如下:

drawable-xxhdpi > drawable-xxxhdpi > drawable-nodpi  > drawable-xhdpi > drawable-hdpi > drawable-mdpi > drawable-v24 27 28... > drawable  > drawable-ldpi

 dpi为420的手机,没有直接匹配的资源目录,它会先匹配与之相近目录 xxhdpi, 与dpi为480的手机匹配规律是一样的,但是该手机计算ImageView和 Bitmap尺寸时,相同的图片计算的结果是不一样的。

同一张图片,放在不同密度的Drawable文件夹下,ImageView设置src,宽高为warp_content,ImageView被加载出来的实际尺寸的规律

备注:测试手机型号  华为p30 pro  1080*2340 ,屏幕宽度360dp , dpi 为480 ,1dp == 3px。图片尺寸为100px*100px,下面的记录的值均为宽度。

ImageView宽度bitmap宽度bitmap ByteCount比例压缩
图片所在目录pxdppxdpbytekb图片像素与imageView的像素尺寸比例图片像素与imageView的dp尺寸比例图片占用内存大小比例
drawable-xxxhdpi7525752522500213/41/43/4
drawable-xxhdpi1003310033400003911/31
drawable-nodpi1003310033400003911/31
drawable-xhdpi150501003340000393/21/21
drawable-hdpi2006710033400003922/31
drawable-mdpi300100100334000039311
drawable-v24
drawable
drawable-ldpi40013310033400003944/31

情景一:图片放置于drawable目录时,imageView的宽高均为300px,100dp,而bitmap的尺寸为100*100,bitmap占用的内存大小为100*100*4byte。

情景二:图片放置于drwable-xxxhdpi目录时,imageview宽度为75px,这是因为手机的dpi为480,匹配的xxhdpi,xxhdpi中没有资源,会向上寻找,xxxhdpi中有资源,但根据android系统匹配原理,这个目录下的图片,相对于这款手机来说,需要进行压缩处理,它会按原尺寸的3/4进行裁剪,这样imageView bitmap等的尺寸都会变小,显示在屏幕上的图片也会变小。

实际加载的UI情况如下:

测试环境:华为P30 手机  dpi = 480, 1dp = 3px, 屏宽为360dp。 屏幕尺寸:1080*2340 

图片尺寸:100*100px 。图片为网格图形,每一个网格为10px*10px



 

结论:同一款手机,同一张图片,图片放在不同密度的drawable文件夹下,计算出来的drawable尺寸是不一样的。

不同dpi的手机,同一张图片,放在不同密度的Drawable文件夹下,ImageView被加载后,ImageView尺寸和Bitmap尺寸。

条件:

1)图片尺寸为100*100 px

2) ImageView设置src,宽高设置wrap_content,

手机终端图片宽度100
手机型号Samsung Galaxy S20 Ultra 5GGoogle Pixel XL华为p30Google Nexus 5X
系统版本10(29)10(29)
手机尺寸(单位:英寸)6.9 5.5 6.1 5.2 5.5 
分辨率1440 x 30401440 x 25601080 x 23401080 x 1920 720 x 1280
屏幕尺寸(单位:dp)360 x 760 411 x 731360 x 780 411 x 731360 x 640
dpi640 560480420320
density43.532.6252
匹配资源目录drawable-xxxhdpidrawable-xxxhdpidrawable-xxhdpidrawable-xxhdpidrawable-xhdpi
资源资源目录系统dpi基准比例ImageView宽度(单位px)Bitmap宽度(单位px)图片缩放比例ImageView宽度(单位px)Bitmap宽度(单位px)图片缩放比例ImageView宽度(单位px)Bitmap宽度(单位px)图片缩放比例ImageView宽度(单位px)Bitmap宽度(单位px)图片缩放比例ImageView宽度(单位px)Bitmap宽度(单位px)图片缩放比例
drawable-xxxhdpi6404100 100 1.00 88 88 0.88 75 75 0.75 66 66 0.66 50 50 0.50 
drawable-xxhdpi4803133 100 1.33 117 100 1.17 100 100 1.00 88 88 0.88 67 67 0.67 
drawable-xhdpi3602200 100 2.00 175 100 1.75 150 100 1.50 131 100 1.31 100 100 1.00 
drawable-hdpi2401.5267 100 2.67 233 100 2.33 200 100 2.00 175 100 1.75 133 100 1.33 
drawable-nodpi1601400 100 4.00 350 100 3.50 300 100 3.00 263 100 2.63 200 100 2.00 
drawable-mdpi
drawable-v24
drawable
drawable-ldpi1200.75533 100 5.33 467 100 4.67 400 100 4.00 350 100 3.50 267 100 2.67 

总结:

1)不同dpi的终端加载 相同屏幕密度目录下的同一张图片,显示效果会有差异

2)同一个终端加载同一张图片,控件宽高设置为wrap_content,图片放在不同的密度目录下,显示的效果不一样。规律:密度越小的drawable目录下,图片显示出来的尺寸就越大。当然是要ImageView的宽度设置和图片尺寸符合要求的情况。

ImageView尺寸计算规律:

手机终端的dpi / 图片所在资源目录对应的dpi *  图片尺寸。

例如 华为P30,dpi = 480, 如果图片放在xxxhdpi目录下,则ImageView的尺寸为  480 / 640 * 100px = 75px,它对就的bitmap的尺寸也是75px * 75px;如果图片在xhdpi, 则ImageView的尺寸为 480/ 360 * 100px = 100 * 1.5 = 150px.

Bitmap占用内存计算

Bitmap占用内存大小计算公式

Bitmap占用内存大小 =  bitmap宽度 * bitmap高度 * 每个像素占用的字节数

Bitmap占用内存实测

测试条件:图片尺寸100px*100px ,ImageView宽高为wrap_content.

手机华为p30 prostudio模拟器vivo x7
系统版本29(10)30(11)22(5.1)
屏幕尺寸1080*2340 1080x1920 1080x1920
屏幕宽度(dp)360dp411dp360dp
dp/px1dp=3px1dp=2.6251dp=3px
dpi480420480
bitmap内存大小drawable-xxxhdpi22500(21kb)

66*66*4=17424

22500(21kb)
drawable-xxhdpi40000(40kb)88*88*4=3097640000(40kb)
drawable-nodpi40000(40kb)40000(40kb)36000(351kb)
drawable-xhdpi40000(40kb)90000(87kb)
drawable-hdpi40000(40kb)160000(156kb)
drawable-mdpi40000(40kb)360000(351kb)
drawable-v2440000(40kb)
drawable40000(40kb)
drawable-ldpi40000(40kb)640000(625kb)

结论:

1) 低密度手机匹配到高密度的资源目录中图片资源,实际加载中,会压缩图片尺寸。

例:dpi 420 的模拟器,屏幕宽度411dp,1080*1920,density 为2.625。 dpi420在 xhdpi(320)与xxhdpi(480)之间,根据匹配原则,它会向更高密度资源目录匹配,匹配的是xxhdpi。此时 Bitmap宽度 = 图片宽度(100px)  *  420 /  480 = 88px。如果xxhdpi没有资源,则会向更高密度的资源目录中匹配,此时Bitmap宽度= 100px * 420 / 560 = 66 px。

2)Bitmap尺寸与ImageView的尺寸并无直接关系,Bitmap尺寸的计算与图片所在的资源目录位置有关,放在不同的资源目录计算结果有差异。

例:一张1500px*1000px的图片放在480dpi 手机(华为p30 )中的drawable目录下,对应的Bitmap对象尺寸为1500px*1000px,与ImageView的实际尺寸无关。

3)Bitmap尺寸在大部分手机上面,会有上限值,即不会超过原图的尺寸,但在测试机vivo x7 5.1系统上,bitmap的尺寸与图片实际显示的尺寸相关联,且会超过原图尺寸,放在越小密度目录下,加载出来的图片越耗内存。Bitmap的计算原理在不同系统上面会有差距,还不知道具体从哪一系统版本发生改变的。

实践:如下图右上角红框中的图标按钮,如何让一个ImageView正常显示图片,且具有点击事件,同时需要扩大该按钮点击区域。

 分析:ImageView显示的图片不能被但伸或裁剪,点击区域比图片显示的区域要大

解决方案:将ImageView宽高值确定,固定的宽高值或是设置macth_parent, ImageView设置属性 android:adjustViewBounds="true" ,保证图片根据ImageView尺寸等比例缩放,再根据UI图,由ImageView的宽高和图片在UI图中宽高来计算该图片在ImageView的左右上下的padding值,设置完成padding之后就可以满如上需求了。这样做的意义是扩大点击区域,保证Ui高保真实现,不需要由多个控件组合完成,减少view层级。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值