bitmap是一个吃内存的大家伙,如果使用不当,那么程序就会OOM常伴了。因此,这篇文章主要介绍几个方法来控制好bitmap对内存的占用。
第一种方法:按比例缩小bitmap
private Bitmap getBitmap(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始是先把newOpts.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts); // 此时返回bitmap为null
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 以800*480分辨率为例
float hh = 800f; // 这里设置高度为800f
float ww = 480f; // 这里设置宽度为480f
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int scale = 1; // be=1表示不缩放
if (w > h && w > ww) { // 如果宽度大的话根据宽度固定大小缩放
scale = (int) (newOpts.outWidth / ww); </span>
} else if (w < h && h > hh) { // 如果高度高的话根据宽度固定大小缩放
scale = (int) (newOpts.outHeight / hh);
} if (scale <= 0) scale = 1; newOpts.inSampleSize = scale; // 设置缩放比例 // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return bitmap;
}
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);
并不会返回一个bitmap,即返回的是null。此时可以再newOpts中取得这个bitmap的宽高。接下来,我们就可以用来计算要缩小的比例尺了。
注意:scale计算出来的值大于1的话,假设为n(n>1,n为int型),则表示要bitmap要缩小为原来的1/n。计算得到比例尺之后,设置到
newOpts.inSampleSize = scale; // 设置缩放比例
此时还要不忘设置
newOpts.inJustDecodeBounds = false;
接着重新解析bitmap,即可获得缩小后的bitmap
第二种方法:按指定大小来缩小bitmap
// 按实际的大小生成的Bitmap
Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), mImageIds[arg0]);
bm = Bitmap.createScaledBitmap(bm, width, height, false);
在Bitmap中,有一个方法可以来缩放bitmap,使用起来十分简便。在createScaledBitmap中传入自己指定的宽高,即可让bitmap按比例缩小。减低其对内存的占用。
经过我的测试,以上两种方法都能够有效的缩小bitmap对内存的占用,当一张很大的图片解析成bitmap时,可能会达到1M以上,此时,将会很容易造成OOM。
但是经过上面两种方法的压缩之后,bitmap能够按照需要的宽高来缩小,从而有效的降低内存的占用。解释一下为什么能减低内存的占用:假设一个bitmap的宽高分别缩小到原来的1/4,那么它所占用的大小为宽乘以高,即为原来的1/4 * 1/4 = 1/16。所以能够有效降低内存占用。