最近在使用bitmap采样时发现,采样后的大小比采样前还要大。 这是怎么回事呢? 原来是我忽略了一个相关知识点。
代码如下:
BitmapFactory.Options options = new BitmapFactory.Options();
// 设置仅解码宽高。 在options中有in开头的属性,一般是用来设置的。 带out开头的属性一般是输出相关信息的。
options.inJustDecodeBounds = true;
// 设置后,这次decode会返回null,所以不要使用此时返回的bitmap
BitmapFactory.decodeResource(getResources(), R.drawable.test, options);
Log.i(TAG, "simpleSize before: " + options.outWidth + ", " + options.outHeight);
// 设置采样率。 这里使用的是google推荐的采样方法。
int sampleSize = calculateInSampleSize(options, Utils.getActivityWidth(this), Utils.getActivityHeight(this));
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
Bitmap originBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test, options);
Log.i(TAG, "simpleSize after: " + originBitmap.getWidth() + ", " + originBitmap.getHeight());
其中,采样的方法如下:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
打印的结果如下:
通过日志发现,采样后的图片大小反而变大了。 断点调试时,采样率是 1,至少不会变大。 为啥呢?
**原来通过 BitmapFactory.Options 设置 inJustDecodeBounds 为 true的方式取出的宽高值是图片原本的值。**打开文件管理器查看图片的宽高为 1200 和 760 像素。
但是通过 设置 inJustDecodeBounds 为 false的方式,则会根据系统屏幕密度对图片进行缩放。
首先,要看图片是放在哪个文件夹下的。假设设备屏幕密度是 m。 如果是drawable文件夹下,那么图片的缩放的比例是 m / 160 ,
如果是drawable-mdpi,那么图片的缩放比例是 m / 240 , 同理其他的文件夹。 由此可知,图片的缩放比例是屏幕密度除以图片所在文件夹对应的屏幕密度。
在上例中,图片放在了drawable中,对应的屏幕密度是 160(drawable使用的是基准值 160), 而设备的屏幕密度为 320 。
故解析出来的bitmap大小是实际图片的 320 / 160 = 2 倍。 如果放在drawable-hdpi中,那么解析出来的图片宽度将是 320 / 240 * 1200 (1200是实际宽度) = 1600, 实际打印也如此:
总结:
1、通过 BitmapFactory.Options 获取的是图片实际大小,不会随系统改变。
2、通过 BitmapFactory 得到的 Bitmap 大小会根据系统缩放,缩放比例为 屏幕密度 / 图片文件夹对应屏幕密度。
3、当从本地加载图片时不会对图片进行缩放。