Android BitmapFactory 解码总结

来源:互联网 发布:apache bench post 编辑:程序博客网 时间:2024/05/26 02:52

 使用BitmapFactory解码图片

解码本地图片

final BitmapFactory.Options option = new BitmapFactory.Options();// inDensity表示当前的Bitmap的像素密度option.inDensity = DensityUtil.densityDpi;// 使用inScale=true, 表示解码图片时允许图片缩放// option.inScaled = true;// inTargetDensity 表示需要解成Bitmap的像素密度final Bitmap bitmap = BitmapFactory.decodeFile(path, option);

这样解码仍然会存在问题,假如本地图片是3X图,那么解码完放在2X手机上会造成资源浪费,此时需要根据ImageView的大小动态调整Bitmap的大小,这样可以减少内存占用,同时避免OOM

使用inJustDecodeBounds进行测量Bitmap的宽高

使用inJustDecodeBounds=true, 然后使用BimapFactory.decodeXXX()这样不会造成真正的内存分配,但是此时通过Option可以拿到Bitmap的真实宽高
然后根据View的宽高调整Bitmap的宽高,即计算Bitmap的采样率(inSampleSize)

inSamplleSize的计算

inSampleSize必须是2的n次幂,这个inSampleSize的意思是宽高都缩减为这个值
计算规则如下:
reqWidth, reqHeight为View的需要宽高
option中携带Bitmap的宽高

/**     * Method allows to find out the scale which can be applied when loading image in order to save memory     *     * @param options   preset and preloaded option of an image     * @param reqWidth  required width of image     * @param reqHeight required height of image     * @return scaling of image to be applied while loading the image (as power of 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;        // 如果Bitmap的宽高大于View的宽高        if (height > reqHeight || width > reqWidth) {            // 均除2            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                inSampleSize *= 2;            }        }        return inSampleSize;    }

使用BitmapFactory进行解码的代码

public void parseDrawable(final List<Pair<View, String>> list, final OnLoadBitmapCallback callback) {        if (list == null || callback == null || list.isEmpty()) {            return;        }        final List<Pair<View, BitmapDrawable>> drawables = new ArrayList<>();        for (Pair<View, String> p : list) {            final BitmapFactory.Options option = new BitmapFactory.Options();            option.inJustDecodeBounds = true;            // just decode bound.            BitmapFactory.decodeFile(p.second, option);            // 计算真实图片图片比例            option.inSampleSize = calculateInSampleSize(option, p.first.getWidth(), p.first.getHeight());            option.inJustDecodeBounds = false;            // inPrefreredConfig表示优先选用的解码模式            // 但是RGB_565没有ALPHA通道,且只能表示65525中颜色            // 如果需要解码的图片含有ALPHA通道那么系统仍然会选用RGB_8888进行解码            // 忽略InPreferedConfig            option.inPreferredConfig = Bitmap.Config.RGB_565;            final Bitmap bitmap = BitmapFactory.decodeFile(p.second, option);            if (bitmap != null) {                BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);                bitmapDrawable.setTargetDensity(DensityUtil.DISPLAY_METRICS);                bitmapDrawable.setTileModeXY(Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);                drawables.add(new Pair<>(p.first, bitmapDrawable));            }        }        callback.onLoadBitmap(drawables);        });    }
阅读全文
0 0