你的 Bitmap 究竟占多大内存?

参考:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498

            http://blog.csdn.net/guolin_blog/article/details/50727753


实际情况:一张 522x686 的 PNG 图片,我把它放到 drawable-xxhdpi 目录下,在三星s6上加载,占用内存2547360B。


自己计算的情况:一张 522*686PNG  图片,我把它放到   drawable-xxhdpi  目录下,在 三星s6上加载。其中xxhdpi 对应的 density  为480,targetDensity 对应三星s6的密度为640,所以:
522/480 * 640 * 686/480 *640 * 4 = 2546432B, 和上面的实际情况是不一样,有误差的,误差哪里来的?接着往下看!


哪里有误差,追踪源码,源码给出的计算方法如下:
在我们的例子中,
scaledWidth = int( 522 * 640 / 480f + 0.5) = int(696.5) = 696
scaledHeight = int( 686 * 640 / 480f + 0.5) = int(915.16666…) = 915
然后
915 * 696 * 4 = 2547360。这下就对了!

所以,在你的APP适配屏幕的时候,一定要多做几套图。不要觉得好像在drawable-xxhdpi放一套图我的app运行起来好像也没有问题啊,实则不然。适用于ppi为640的图你放到ppi为320的设备中显示的话,内存会是4倍。(后面这两句话不对)


实例分析:

lhdpi:120      mhdpi:160    hdpi:240     xhdpi:320     xxhdpi:480      xxxhdpi:640

如果我的app中有一个imageview,宽和高为100*100,那么在适配S6(ppi为640)我在xxxhdpi中放了一个100*100的图片,那么此图在S6的这个imageview中占内存为         ( 100 * 640 / 640 + 0.5)*( 100 * 640 / 640 + 0.5)*4也就是40401B(精确值,按照源码中的方法算出来的)。

如果我在xxxhdpi中没存放图片,只在xhdpi中放了个100*100的图片,那么这个app中的这个imageview会占多少内存呢?计算如下:

(100*640/320 + 0.5)*(100*640/320 + 0.5) *4= 160801B(精确值,按照源码中的方法算出来的),  约4倍于直接把此图放在与设备dpi(S6的dpi为640)相近的资源文件夹xxxhdpi中。

为什么会是四倍呢?因为S6从与它DPI接近的xxxhdpi找不到图片,然后在xhdpi中找到图片,因为xhdpi对应的dpi是320,而xxxhdpi对应的dpi是640,我把你320的图片拿过来当做640的用,肯定要对你进行放大,宽和高分别放大(640/320 = 2)倍,所以占用内存就是4倍了。如果在xhdpi也没找到,而只在mhdpi中找到,那么就要把宽和高分别放大(640/160 = 4)倍了,那么占用内存就不是4倍,而是16倍了。


上面说的是设备DPI高于图片所存放的文件夹的dpi的情况:系统把图片拿过来用时会自动把图片放大,所以内存占用也是原来的数倍甚至是多倍。

如果我的设备dpi小于图片所在的文件夹的dpi,那么系统把图片拿过来用时会不会自动把图片缩小呢?确实是这样的!

如果适配时我只在xxxhdpi:640放置了图片100*100,而我的设备是320的,那么设备在对应的xhdpi:320找不到图片就会去xxxhdpi:640文件夹中寻找,那么在我的设备中,此图片占多少内存呢?计算如下:

(100*320/640 + 0.5)*(100*320/640 + 0.5) *4 = 2550B。


所以我们UI给图的时候,"就目前来讲,最佳放置图片资源的文件夹是drawable-xxhdpi"。为什么呢?

比方说我在我的代码中固定一个imageview的宽高是100*100DP,那么在mhdpi:160放的图片就必须是100*100,hdpi:240是150*150, xhdpi:320是200*200, xxhdpi:480存放的是300*300, xxxhdpi:640是400*400。这样的话,在不同的手机上,这个imageview看起来是差不多大的。

但是现实情况是UI不会做这么多图的,他们只会给出一套图,那我们要低密度的图还是高密度的图呢?肯定是要相对来说密度较高的图。

比方说UI给我们的只有300*300的,我们把它放在xxhdpi下,但是我的设备dpi是158(接近160),因为只有这一套图,那么系统会去xxhdpi取图,但是取过来之后,会进行相应的缩小,怎么缩小?宽高分别缩小(xxhdpi/mhdpi,也就是480/160)3倍,那么300*300缩小为100*100了,刚好在我的160的设备上用。不浪费也不会显得很模糊。


还是总结一下:

1.图片占用多大内存?和设备DPI以及图片所在文件夹对应的dpi有关,因为计算公式:

(设备DPI / 图片所在文件夹所对应的dpi * 图片宽度 + 0.5)*(设备DPI / 图片所在文件夹所对应的dpi * 图片高度 + 0.5)*图片每个像素占用的字节数(ARGB_8888占4个)

2.图片放大或者缩小多少倍?和设备DPI所对应的文件夹的dpi以及图片所在的文件夹所对应的dpi有关:

比方我设备dpi是620,“设备DPI所对应的文件夹的dpi”是640,而图片存在于 xhdpi:320 ,那么图片宽高分别放大两倍。

比方我的设备dpi144,“设备DPI所对应的文件夹的dpi”就是160,而图片存在于 xxhdpi:480,那么图片宽高分别缩小 3倍。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值