我们在开篇中说过 android 中图片占用内存的大小是由图片本身的分辨率和像素格式还有图片所在drawable 文件夹有关系,那么有时候我会有这样的疑问:比如图片很大,那么我把 imageview 宽高设置的很小,会不会节约一些内存。一直以来我都有这个疑问,正好今天开始整理自己的图片知识体系,那么就随便做个测试好了。
我设计了一个对比,一个页面里从上到下有6个 宽高不同的imageview,前3个 imageview 使用同一张 png 图片,后3个 imageview 使用2张尺寸不同的 SVG 图片,然后我们打印出此时 imageview 中 drawable 的实际宽高和占用内存大小。
涉及图片:
一张 PNG 图: 72*72
2张 SVG 矢量图: 24dp*24dp,48dp*48dp
6个 imageview
前3个 imageview 都时使用这张 PNG 图片的
view宽高:match_parent*wrap_content,72px*72px,48dp*48dp
后3个 imageview 使用2张 SVG 图,SVG1,SVG2
SVG1:24dp*24dp , SVG2:48dp*48dp
view宽高:50dp*50dp/SVG1,50dp*50dp/SVG2,10dp*10dp/SVG1
看下结果:
代码很简单,我就贴一下获取宽高和内存大小的代码
// 获取图片宽高
Rect bounds = image.getDrawable().getCurrent().getBounds();
result = "宽:" + (bounds.right - bounds.left) + ",高:" + (bounds.bottom - bounds.top);
// 获取 png 图片占用内存大小
Drawable drawable = image.getDrawable();
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
result = result + "内存:" + (bitmap.getAllocationByteCount() / 1024) + "KB";
} else {
result = result + "内存:" + calculateSVGDrawableSize(drawable) + "KB";
}
// 获取 SVG 矢量图占用内存大小
private float calculateSVGDrawableSize(Drawable drawable) {
Bitmap bitmap = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
return bitmap.getAllocationByteCount() / 1024;
}
结论
PNG 图片部分:
我们修改 imageview 的大小并不会影响PNG图片占用内存大小,所以把 imageview 写的小一点省内存就是个错觉,哈哈,我一直以来都有这个错觉哈。所以说 png 图我们能把分辨率做小就做小,真心吃内存啊,
SVG 矢量图部分:
同样我们修改 imageview 的大小并不会SVG影响图片占用内存大小,需要注意的是 SVG 图片实际的显示分辨率是由SVG 的 xml文件中的 width/height 决定的,所以啊SVG 既然支持缩放,那我们就把宽高写小了好了,这样可以省内存呀。
2张 SVG图:
SVG1
SVG2