首页 > 代码库 > Loading Large Bitmaps Efficiently
Loading Large Bitmaps Efficiently
NOTE:看来Android文档过来做个笔记,并没有详细去写这些东西。
BitmapFactory提供的decode方法直接去decode的话,会造成oom异常。
要设置BitmapFactory.Options 的inJustDecodeBounds为true。将图片信息decode出来,此时并没有真正的加载图片,只是获取了边界信息和图片mimetype
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;
往往一个Imageview很小,但是一个图片很大,这时加载时就需要将图片压缩到ImageView差不多大小加载能有效的节约内存:
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,Android文档中是这么描述inSampleSize的:
If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder uses a final value based on powers of 2, any other value will be rounded down to the nearest power of 2.
意思就是说inSample不管你算出来是多少,最后都被四舍五入到了2的倍数。
加载图片时就可以这么加载了:
首先获取到图片的实际大小,然后输入你实际想要的大小。获取到缩放倍数,再将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));
Loading Large Bitmaps Efficiently