1.Read Bitmap Dimensions and Type 读取图片的尺寸和类型 java
//建立一个Options,用于保存图片的参数 BitmapFactory.Options options = new BitmapFactory.Options(); //设置是否只读取图片的参数信息 options.inJustDecodeBounds = true; //因为inJustDecodeBounds被设置为了true,此处只会得到图片的参数信息 //而不会读取到Bitmap对象,也就不会占用内存 BitmapFactory.decodeResource(getResources(), R.id.myimage, options); //得到图片的宽高以及类型 int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType;
为了不java.lang.OutOfMemory异常,在将一张图片解析为Bitmap对象以前,必定要检查它的尺寸. spa
2.Load a Scaled Down Version into Memory 加载通过缩放的图片到内存中 code
既然咱们已经知道了图片的尺寸,咱们就知道是否有必要将原图加载到内存中.咱们能够有选择的将图片通过缩放后再加载到内存中. 对象
须要考虑的因素有如下几点: 图片
1.预估加载原图须要的内存大小 内存
2.你愿意给这张图片分配的内存大小 ci
3.要显示这张图片的控件的尺寸大小 get
4.手机屏幕的大小以及当前设备的屏幕密度 it
举例说明,若是你想要显示一张128×96像素的缩略图,则加载一张1024×768像素的图片是没有必要的. io
为了告诉解码器去加载一张通过缩放的图片,须要设置BitmapFactory.Options的inSampleSize参数.
例如:一张图片的原始大小是2048×1536,若是将inSampleSize设置为4,则此时加载的图片大小为512×384,加载通过缩放后的图片只须要0.75MB的内存控件而不是加载全图时须要的12MB.
如下是一个计算inSampleSize的方法:
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; // 默认缩放比例为1 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. // 计算inSampleSize的值,该值是2的次方,而且可以保证图片的宽高大于指定的宽高 while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
要想使用上述方法,首先要讲inJustDecodeBounds设置为true,读取到图片的尺寸信息,再通过计算获得的inSampleSize去解析图片
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions // 此处将inJustDecodeBounds设置为true,则只解析图片的尺寸等信息,而不生成Bitmap final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize // 此处计算须要的缩放值inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set //将inJustDecodeBounds设置为false,以便于解析图片生成Bitmap options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }