本文共 3190 字,大约阅读时间需要 10 分钟。
我用的图片主要分为3种 1、质量压缩 ,2、尺寸压缩,3、Luban压缩(鲁班)
一、质量压缩
质量压缩的特点是: File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变
质量压缩主要借助Bitmap中的compress方法实现:
public boolean compress (Bitmap.CompressFormat format, int quality, OutputStream stream)
这个方法用来将特定格式的压缩图片写入输出流(OutputStream)中,当然例如输出流与文件联系在一起,压缩后的图片也就是一个文件。如果压缩成功则返回true,其中有三个参数:
下面是质量压缩的代码:
二、尺寸压缩
特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩
我们主要通过BitmapFactory中的decodeFile方法对图片进行尺寸压缩:
public static Bitmap decodeFile (String pathName, BitmapFactory.Options opts)
其中有两个参数:
boolean inJustDecodeBounds —— 如果设置为true,则只读取bitmap的宽高,而忽略内容。
int inSampleSize—— 如果>1,调用decodeFile方法后,就会得到一个更小的bitmap对象(已压缩)。比如设置为2,那么新Bitmap的宽高都会是原Bitmap宽高的1/2,总体大小自然就是原来的1/4了,以此类推。
boolean inPurgeable—— 如果设置为true,压缩后的图片像素占的内存将会在系统清理内存的时候被回收掉,当像素的信息再次被用到时将会自动重新decode该像素(比如getPixels()时)。(慎用!重复decode可以会造成UI的卡顿,API level 21 已弃用)
boolean inInputShareable—— 与inPurgeable配合使用,如果inPurgeable设置成false,自动忽略此值,如果inPurgeable为true,此值决定是否该bitmap能分享引用给输入数据(inputstream,array等),或者必须进行深拷贝。API level 21 已弃用。(这是译文,不太理解!!!)
下面是一段实现的代码
private Bitmap sizeCompres(String path, int rqsW, int rqsH) {
// 用option设置返回的bitmap对象的一些属性参数
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 设置仅读取Bitmap的宽高而不读取内容
BitmapFactory.decodeFile(path, options);// 获取到图片的宽高,放在option里边
final int height = options.outHeight;//图片的高度放在option里的outHeight属性中
final int width = options.outWidth;
int inSampleSize = 1;
if (rqsW == 0 || rqsH == 0) {
options.inSampleSize = 1;
} else if (height > rqsH || width > rqsW) {
final int heightRatio = Math.round((float) height / (float) rqsH);
final int widthRatio = Math.round((float) width / (float) rqsW);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
options.inSampleSize = inSampleSize;
}
return BitmapFactory.decodeFile(path, options);// 主要通过option里的inSampleSize对原图片进行按比例压缩
}
三、Luban压缩
这里介绍下一个第三方开源库——
上面两图中的上部分图片是原图,下面部分是经过Luban压缩过后的图片
效果:
第一张原图4.55m 尺寸3456x4608。 压缩过后53k 尺寸1152x1536
第二张原图1.16m 尺寸1080x1920。 压缩过后150k 尺寸360x640
我们可以发现压缩后的图片在不放大的情况下,图片效果和原图一致,Luban的处理效果特别好。
如何使用Luban压缩图片
1.在项目中的build.gradle添加依赖(需要用到RxJava1.0)
2.在代码中使用Luban压缩方法
1)Listerner方式。传入图片File,调用设置压缩监听setCompressListerner方法,处理压缩结果。
2)Rxjava方式,传入图片File,调用asObservable方法返回一个Observable观察者对象,使用RxJava方式来处理压缩结果。
源码中最主要的方法就是thirdCompress(File file),即如何计算得出理想的压缩后宽高,以及图片大小。
1.不能很好的支持多图片压缩。(出现问题:多图压缩出现OOM)
2.项目使用中必须添加RxJava依赖。(已在测试项目中剔除掉RxJava依赖 )