Android 图片二次采样
android图片加载 由于手机内存的原因,大位图往往会是手机OOM,所以需要对图片进行相应的压缩。
android中提供了一个类
BitmapFactory.Options
public class BitmapFactory { private static final int DECODE_BUFFER_SIZE = 16 * 1024; public static class Options { /** * Create a default Options object, which if left unchanged will give * the same result from the decoder as if null were passed. */ public Options() { inDither = false; inScaled = true; inPremultiplied = true; } ....... public void requestCancelDecode() { mCancel = true; requestCancel(); } } }
从源码可以知道我们想要获得一个图片对象必须要提供一个Options对象参数,如以下两个方法
public static Bitmap decodeFile(String pathName) { return decodeFile(pathName, null); } /** * Decode a new Bitmap from an InputStream. This InputStream was obtained from * resources, which we pass to be able to scale the bitmap accordingly. */ public static Bitmap decodeResourceStream(Resources res, TypedValue value, InputStream is, Rect pad, Options opts) { if (opts == null) { opts = new Options(); }
因此必须先获取一个options对象,在options里面有几个成员变量:inJustDecodeBounds
/** * If set to true, the decoder will return null (no bitmap), but * the out... fields will still be set, allowing the caller to query * the bitmap without having to allocate the memory for its pixels. */ public boolean inJustDecodeBounds; /** * The resulting height of the bitmap. If {@link #inJustDecodeBounds} is * set to false, this will be height of the output bitmap after any * scaling is applied. If true, it will be the height of the input image * without any accounting for scaling. * * <p>outHeight will be set to -1 if there is an error trying to decode.</p> */
从注释可以了解到,当设置为true时,会返回null,即得不到bitmap,但允许去获取图片资源的宽高
当设置为false时,则返回视图
inSampleSize,设置相应的压缩比
public int inSampleSize; /** * If this is non-null, the decoder will try to decode into this * internal configuration. If it is null, or the request cannot be met, * the decoder will try to pick the best matching config based on the * system's screen depth, and characteristics of the original image such * as if it has per-pixel alpha (requiring a config that also does). * * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by * default. */
对图片的使用到的就是这两个变量,下面是完整代码
public class ImageResizer { // private static final String TAG = "ImageResize"; public ImageResizer() { } //这里是从资源里面加载图片,其他方法也是一样的 public Bitmap decodeSampleBitmapFromResource(Resources res , int resId , int reqWidth , int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true;//设置为true,第一次采样只获取图片原始宽高度,并没有将图片加载
BitmapFactory.decodeResource(res, resId, options);//可以使用获得图片原始宽高度 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds=false; return BitmapFactory.decodeResource(res, resId, options); } private int calculateInSampleSize(BitmapFactory.Options options , int reqWidth , int reqHeight) { if (reqWidth == 0 || reqHeight == 0) { return 1; } //获取原图的宽高 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; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } /** 另外一种获取压缩比例的写法 int inSampleSize = Math.round ( (float) (height/reqHeight)) > Math.round ( (float) (width/reqWidth)) ? Math.round ( (float)(height/reqHeight)) :Math.round ( (float)(width/reqWidth)); */
} return inSampleSize; } }
浙公网安备 33010602011771号