生成一个Bitmap,主要有两种形式 Bitmap的静态方法和BitmapFactory的静态方法(decode);
Bitmap的enum有两个:Bitmap.CompressFormat定义图片格式PNG,JPEG,WEBP;Bitmap.Config定义图片属性,ARGB-8888(4个字节),GRB-565(2个字节),ARGB-4444(弃用建议使用8888),ALPHA-8;
BitmapFactory提供了一些解码(decode)方法(decodeByteArray(), decodeFile(), decodeResource()等),用来从不同的资源中创建一个Bitmap。每一种解码方法都可以通过BitmapFactory.Options设置一些附加的标记,以此来指定解码选项。设置 inJustDecodeBounds 属性为true
可以在解码的时候避免内存的分配,它会返回一个null
的Bitmap,但是可以获取到 outWidth, outHeight 与 outMimeType。该技术可以允许你在构造Bitmap之前优先读图片的尺寸与类型。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
一个分辨率为2048x1536的图片,如果设置 inSampleSize 为4,那么会产出一个大约512x384大小的Bitmap。加载这张缩小的图片仅仅使用大概0.75MB的内存,如果是加载完整尺寸的图片,那么大概需要花费12MB(前提都是Bitmap的配置是 ARGB_8888)。根据目标图片大小来计算Sample图片大小的代码示例:
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;
}
为了使用该方法,首先需要设置 inJustDecodeBounds 为 true
, 把options的值传递过来,然后设置inSampleSize 的值并设置 inJustDecodeBounds 为 false
,之后重新调用相关的解码方法。
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
使用上面这个方法可以简单地加载一张任意大小的图片。如下面的代码样例显示了一个接近 100x100像素的缩略图:
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
我们可以通过替换合适的BitmapFactory.decode* 方法来实现一个类似的方法,从其他的数据源解析Bitmap。