【读取位图尺寸和类型】
BitmapFactory类提供了一些解码方法 (decodeByteArray(), decodeFile(), decodeResource(), 等.) 从各种源来创建位图Bitmap。选择最合适的解码方法依赖于你的图片数据源。这些方法试图按照bitmap的构造方法分配内存,因此很容易导致OutOfMemory异常。每一种解码方法还有额外的通过 BitmapFactory.Options来指定解码选项的签名,在解码时设置inJustDecodeBounds属性为真可以避免分配内存,虽然返回的是空位图,但是图片的outWidth,
outHeight 和outMimeType属性已经获得。这种技术可以让在创建位图(和内存分配)前获取位图的尺寸和类型。
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;
为了避免 java.lang.OutOfMemory 内存溢出异常,在解码图片前要检查图片的尺寸,除非确信为您提供的是可预见尺寸的,占用内存合适的图像数据源。
【在内存中加载一个缩小版的图片】
现在图片的尺寸已经知道,可以用来在内存中加载全尺寸的图片或者加载缩小的子样本图片。这里有一些因素需要考虑:
*估计加载全尺寸内存使用情况
*对于加载此图片,你的应用程序能够给它分配的内存数量
*此图片装载的ImageView或者UI组件的尺寸
*当前设备的屏幕大小和密度
例如,把1024×768像素的图像载入到内存,如果它最终将在ImageView里显示一个128X96像素的缩略图,这是不值得的。
告诉解码器加载一个缩小版的图片样本到内存,在 BitmapFactory.Options对象里设置 inSampleSize为真,例如一个分辨率为2048*1536的图片用inSampleSize为4解码,将会生成一个约512*384的图片。加载此图片到内存只会占用0.75MB而不是全尺寸的12MB(假设位图配置为ARGB_8888)。下面提供一个方法来计算一个图片样本的大小值,该值是2的幂次方,基于目标宽度和高度计算。
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; }
注意:2的幂次方值的计算,是解码器通过向下舍入到最近的2的幂的值,参见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); }这种方法可以很简单的将任意大的位图以100*100像素的缩略图展现在的ImageView中,就像下面的代码
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));你可以通过相似的方法处理从其他源来解码的位图,通过替换合适的BitmapFactory.decode* 解码方法。
翻译自:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Loading Large Bitmaps Efficiently-高效的加载大位图
原文:http://blog.csdn.net/hil2000/article/details/18968829