第二个方向很好操作,毕竟系统默认是以 ARGB_8888 格式进行处理,那么每个像素点就要占据 4B 的大小,改变这个格式自然就能降低图片占据内存的大小。
常见的是,将 ARGB_8888 换成 RGB_565 格式,但后者不支持透明度,所以此方案并不通用,取决于你 app 中图片的透明度需求,当然也可以缓存 ARGB_4444,但会降低质量。
由于基本是使用图片开源库了,以下列举一些图片开源库的处理方式:
//fresco,默认使用ARGB_8888 Fresco.initialize(context, ImagePipelineConfig.newBuilder(context).setBitmapsConfig(Bitmap.Config.RGB_565).build()); //Glide,不同版本,像素点格式不一样 public class GlideConfiguration implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); } @Override public void registerComponents(Context context, Glide glide) { } } //在AndroidManifest.xml中将GlideModule定义为meta-data <meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration" android:value="GlideModule"/> //Picasso,默认 ARGB_8888 Picasso.with(imageView.getContext()).load(url).config(Bitmap.Config.RGB_565).into(imageView);以上代码摘抄自网络,正确性应该可信,没验证过,感兴趣自行去相关源码确认一下。
降低分辨率如果能够让系统在加载图片时,不以原图分辨率为准,而是降低一定的比例,那么,自然也就能够达到减少图片内存的效果。
同样的,系统提供了相关的 API:
BitmapFactory.Options.inSampleSize设置 inSampleSize 之后,Bitmap 的宽、高都会缩小 inSampleSize 倍。例如:一张宽高为 2048x1536 的图片,设置 inSampleSize 为 4 之后,实际加载到内存中的图片宽高是 512x384。占有的内存就是 0.75M而不是 12M,足足节省了 15 倍
上面这段话摘抄自末尾给的链接那篇文章中,网上也有很多关于如何操作的讲解文章,这里就不细说了。我还没去看那些开源图片库的内部处理,但我猜想,它们对于图片的优化处理,应该也都是通过这个 API 来操作。
其实,不管哪个图片开源库,在加载图片时,内部肯定就有对图片进行了优化处理,即使我们没手动说明要进行图片压缩处理。这也就是我在上面讲的,为什么当你使用了开源图片库后,就不能再按照图片内存大小一节中所讲的理论来计算图片占据内存大小的原因。
我们可以来做个实验,先看下 fresco 的实验:
开源库 前提 Bitmap内存大小fresco 图片位于res/drawable,设备dpi=240,设备1dp=1.5px 1952640B(1.86MB)
fresco 图片位于res/drawable-hdpi,设备dpi=240,设备1dp=1.5px 1952640B(1.86MB)
fresco 图片位于res/drawable-xhdpi,设备dpi=240,设备1dp=1.5px 1952640B(1.86MB)
fresco 图片位于磁盘中,设备dpi=240,设备1dp=1.5px 1952640B(1.86MB)
如果使用 fresco,那么不管图片来源是哪里,分辨率都是已原图的分辨率进行计算的了,从得到的数据也能够证实,fresco 对于像素点的大小默认以 ARGB_8888 格式处理。
我猜想,fresco 内部对于加载 res 的图片时,应该先以它自己的方式获取图片文件对象,最后有可能是通过 BitmapFactory 的 decodeFile() 或者 decodeByteArray() 等等之类的方式加载图片,反正就是不通过 decodeResource() 来加载图片,这样才能说明,为什么不管放于哪个 res 目录内,图片的大小都是以原图分辨率来进行计算。有时间可以去看看源码验证一下。
再来看看 Glide 的实验:
开源库 前提 Bitmap内存大小Glide 图片位于res/drawable,设备dpi=240,设备1dp=1.5px,显示到宽高500dp的控件 94200B(91.99KB)
Glide 图片位于res/drawable-hdpi,设备dpi=240,设备1dp=1.5px,显示到宽高500dp的控件 94200B(91.99KB)
Glide 图片位于res/drawable-hdpi,设备dpi=240,设备1dp=1.5px,不显示到控件,只获取 Bitmap 对象 1952640B(1.86MB)
Glide 图片位于磁盘中,设备dpi=240,设备1dp=1.5px,不显示到控件,只获取 Bitmap 对象 1952640B(1.86MB)
Glide 图片位于磁盘中,设备dpi=240,设备1dp=1.5px,显示到全屏控件(1920*984) 7557120B(7.21MB)
可以看到,Glide 的处理与 fresco 又有很大的不同: