图片质量压缩避免 OutOfMemoryError 内存溢出
当我们使用setImageBitmap
或setImageResource
或BitmapFactory.decodeResource
来设置显示一张大图的时候,经常会遇到 OutOfMemoryError 内存溢出的情况,因为这些函数在完成 decode 后,最终都是通过 Java 层的createBitmap
来完成的,需要消耗很多内存。
改用先通过BitmapFactory.decodeStream
方法,创建出一个 bitmap,再将其设为 ImageView 的 source,因为 decodeStream 是直接调用JNI>>nativeDecodeAsset()
来完成 decode,所以无需再使用 Java 层的 createBitmap,从而节省了 Java 层的空间。
下面是BitmapFactory.Options
的常用属性:
属性 | 描述 |
---|---|
options.inDither = false |
不进行图片抖动处理。 |
options.inJustDecodeBounds |
设置 true 后,decodeFile 并不分配空间,但可计算出原始图片的长度和宽度,即 opts.width 和 opts.height 。有了这两个参数,再通过一定的算法,即可得到一个恰当的 inSampleSize。 |
options.inTempStorage |
设置缓存大小。 |
options.inSampleSize |
对大图片进行压缩的比例。 |
options.inPreferredConfig |
设置图片的解码方式默认是 Bitmap.Config.ARGB_8888 ,如果设置为 null 则自动选最佳方式解码。 |
options.outWidth |
图片的宽度。 |
options.outHeight |
图片的高度。 |
options.inPurgeable 和 inInputShareable |
同时设置让系统能及时回收内存。 |
inPurgeable |
设置为 True 时,表示系统内存不足时可以被回收,设置为 False 时,表示不能被回收。 |
inInputShareable |
设置是否深拷贝,与 inPurgeable 结合使用,inPurgeable 为 False 时,该参数无意义。 |
下面是从指定路径取得图片然后进行压缩的方法:
public static Bitmap revitionImageSize(String path) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
new File(path)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[30 * 1024];//30k缓存
options.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeStream(in, null, options);
in.close();
int i = 0;
Bitmap bitmap = null;
while (true) {
if ((options.outWidth >> i <= 300)
&& (options.outHeight >> i <= 300)) {
in = new BufferedInputStream(
new FileInputStream(new File(path)));
options.inSampleSize = (int) Math.pow(2.0D, i);//设置图片压缩比例
options.inJustDecodeBounds = false;
try {
bitmap = BitmapFactory.decodeStream(in, null, options);
} catch (Exception e) {
// TODO: handle exception
}
break;
}
i += 1;
}
return bitmap;
}
(完)