加载大尺寸的图片时,很容易出现OOM问题。所以需要对原始图片进行一定比例的缩放,再显示出来。
[读取位图的尺寸与类型]
BitmapFactory
类提供了一些decode的方法
(decodeByteArray()
, decodeFile()
, decodeResource()
, etc.)
用来从不同的资源中创建一个
Bitmap
. 根据你的图片数据源来选择合适的decode方法. 那些方法在构造位图的时候会尝试分配内存,因此会容易导致
OutOfMemory
的异常。
每一种decode方法都提供了通过
BitmapFactory.Options
来设置一些附加的标记来指定decode的选项。设置
inJustDecodeBounds
属性为true可以在decoding的时候避免内存的分配,它会返回一个null的bitmap,但是
outWidth
,
outHeight
与
outMimeType
还是可以获取。这个技术可以允许你在构造bitmap之前优先读图片的尺寸与类型。
[计算缩放比例]
拿到尺寸后,计算缩放比例inSampleSize的值,默认为1,大于1则表示缩小这么多倍。
首先需要设置
inJustDecodeBounds
为 true
, 把options的值传递过来,然后使用 inSampleSize
的值并设置 inJustDecodeBounds
为 false 来重新Decode一遍。
/**
* @param path 图片路径
* @param w 显示宽度
* @param h 显示高度
* @return
*/
public static Bitmap scaleBitmap(String path, int w, int h) {
Bitmap bit = null;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
bit = BitmapFactory.decodeFile(path, opts);
DLog.i(TAG, "opts.outHeight=" + opts.outHeight + "opts.outWidth="
+ opts.outWidth);
int imageHeight = opts.outHeight;
int imageWidth = opts.outWidth;
int heightRatio = Math.round((float) imageHeight / (float) h);
int widthRatio = Math.round((float) imageWidth / (float) w );
opts.inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
DLog.i(TAG, "picture inSampleSize " + opts.inSampleSize);
opts.inJustDecodeBounds = false;
try {
bit = BitmapFactory.decodeFile(path, opts);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
return bit;
}