简述
Android 开发中可以使用 BitmapFactory.decodeFile
方法加载图片。如果图片太大就会出现 OOM,所以为了节约内存,在加载时可以设置 Option.inSampleSize
。但 inSampleSize
的取值只能是整数,不能精确缩放到指定尺寸。想要精确缩放,还需要结合 inDensity
、inTargetDensity
使用。
干货
如果不需要知道原理,直接使用下面的方法即可:
/**
* 从指定路径加载一个 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);
}