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; } }

 

posted on 2016-07-01 23:32  metatron  阅读(372)  评论(0)    收藏  举报

导航