Android 如何优雅地加载大尺寸图片

简述

Android 开发中可以使用 BitmapFactory.decodeFile 方法加载图片。如果图片太大就会出现 OOM,所以为了节约内存,在加载时可以设置 Option.inSampleSize。但 inSampleSize 的取值只能是整数,不能精确缩放到指定尺寸。想要精确缩放,还需要结合 inDensityinTargetDensity 使用。

干货

如果不需要知道原理,直接使用下面的方法即可:

/**
 * 从指定路径加载一个 Bitmap, 并限定其最大宽高。
 * 如果文件的宽高大于给定的最大宽高,则会等比例缩放到刚好满足要求。
 * @author 郑海鹏
 */
@Nullable
public static Bitmap decodePhoto(String path, int maxWidth, int maxHeight) {
    // 先获取原始照片的宽高
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);
    int srcWidth  = options.outWidth;
    int srcHeight = options.outHeight;

    // 计算是否需要缩放
    float ratioW = 1F * srcWidth  / maxWidth;
    float ratioH = 1F * srcHeight / maxHeight;
    float ratio  = ratioW > ratioH ? ratioW : ratioH;

    // 尺寸没有超过最大尺寸时,不用缩放
    if (ratio < 1) {
        return BitmapFactory.decodeFile(path);
    }

    // 目标宽度
    int dstWidth = (int) (srcWidth / ratio);

    // 大于4倍时, 先使用 inSampleSize 缩放到目标尺寸的2-4倍
    int inSampleSize = ratio >= 4 ? (int)(ratio / 2) : 1;
    inSampleSize = (int) Math.pow(2, (int)(Math.log(inSampleSize) / Math.log(2)));

    // 再使用 inDensity 精确缩放剩余的部分
    options = new BitmapFactory.Options();
    options.inSampleSize = inSampleSize;
    options.inScaled = true;
    options.inDensity = srcWidth;
    options.inTargetDensity = dstWidth * inSampleSize;
    return BitmapFactory.decodeFile(path, options);
}

你可能感兴趣的:(Android 如何优雅地加载大尺寸图片)