图片加载消耗的内存

图片加载消耗的内存

测试实验的手机及配置

一张图片700*700px 88.2k 测试手机小米k20 分辨率 1080*2340px 测试手机密度440dp

一、通过image src方式加载图片
1
2
3
4
<ImageView
android:src="@mipmap/test_memory"
android:layout_width="300px"
android:layout_height="300px"

1. 放入mipmap-xxxhdpi
无论设置ImageView高宽多少内存分配都是481*481*4 =925476b
这个481 是怎么来的呢
440/640 * 700 = 481.25 向上取整就是缩放转化后的高宽
Alt text

2. 放入mipmap-xxhdpi
无论设置ImageView高宽多少内存分配都是642*642*4 =1648656b
手机精确密度440/ xxhdpi 对应的480dpi*原图高宽700 px = 641.6666 向上取整
Alt text

二、当通过Glide裁剪图片大小的时候

无论图片放在哪个目录mdpi,hdpi,xhdpi,xxhdpi, xxxhdpi 还是网络加载
他的内存都是一样
300*300* 4 = 360032

1
2
3
4
Glide.with(this)
.load(R.mipmap.test_memory)
.override(300, 300)
.into(image)

1
2
3
4
Glide.with(this)
.load("https://mgamevoice2.bs2dl.yy.com/344892b5daac49a9870826beee6b1da5.jpg")
.override(300, 300)
.into(image)

Alt text

总结:

1. 当同imageView src 加载图片的情况
无论设置ImageView高宽多少,对内存分配无效。
bitmap分配的内存 =: 原图缩放的高*原图缩放的宽*每个像素大小
高宽缩放比例 :手机密度/图片所在目录对应dpi

ImageView 加载res图片过程
ResourcesImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@Nullable
private Drawable decodeImageDrawable(@NonNull AssetInputStream ais,
...
try {
return ImageDecoder.decodeDrawable(src, (decoder, info, s) -> {
decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
});
} catch (IOException ioe) {
// This is okay. This may be something that ImageDecoder does not
// support, like SVG.
return null;
}
}

设置高宽大小密度用于创建bitmap
ImageDecoder.java

1
2
3
4
5
6
7
8
9
// This method may modify the decoder so it must be called prior to performing the decode
private int computeDensity(@NonNull Source src) {
...
float scale = (float) dstDensity / srcDensity;
int scaledWidth = Math.max((int) (mWidth * scale + 0.5f), 1);
int scaledHeight = Math.max((int) (mHeight * scale + 0.5f), 1);
this.setTargetSize(scaledWidth, scaledHeight);
return dstDensity;
}

2. 当通过Glide裁剪本地图片大小的情况
无论图片放在哪个目录mdpi,hdpi,xhdpi,xxhdpi, xxxhdpi 还是网络加载
他的内存都是一样 : 裁剪高* 裁剪宽 * 每个像素大小

以上的所说内存分配,bitmap.getAllocationByteCount()可以获得 ,跟getByteCount 不一样

测试的图片
1
2
测试图片地址
https://mgamevoice2.bs2dl.yy.com/344892b5daac49a9870826beee6b1da5.jpg
不同目录对应的dpi

ldpi(低)~120dpi density=0.75
mdpi(中)~160dpi density=1
hdpi(高)~240dpi density=1.5
xhdpi(超高)~320dpi density=2
xxhdpi(超超高)~480dpi density=3
xxxhdpi(超超超高)~640dpi density=4