参考:
1.https://blog.csdn.net/pbm863521/article/details/74391787
2.https://www.jianshu.com/p/871f0c1f0006
1.背景:最近一个项目的开发,需要用到相机拍照,裁剪(使用的是ucrop,推荐使用),保存,上传图片到七牛云的操作,并在上传的过程中遇到了图片过大,服务器返回溢出的错误,难搞哦。在其中发现,如果调用系统的相机,拍出来的图片会有5M的大小,但是调用美图相机的应用,拍照大小只有500k不到,但是用户的手机不可能每个都装美图相机软件,所以需要对图片进行压缩。
2.方法:网上大致的方法分为三种,质量压缩,按比例大小压缩(尺寸压缩),采样率压缩,常用到的有两种,其中采样率压缩不太常用,故不作过多的阐述。主要说一下其他两种。
2.1 质量压缩保持像素的前提下改变图片的位深及透明度(即:通过算法抹掉(同化)图片中的一些某点附近 相近的像素)达到降低质量压缩文件的目的。
2.2 尺寸压缩通过减少单位尺寸的像素值,真正意义上的降低像素(通过缩放图片像素来减少图片占用内存大小)
2.3 第三方开源库近期看资料的时候看到的,鲁班(luban),据说逆向微信图片压缩算法得来的,虽不能完全达到微信效果,但是也很可观了,github上Star已经11K+了,我还没试过,小伙伴可以尝试:https://github.com/Curzibn/Luban
3.代码 (亲测可用) 3.1 指定图片大小,使用缩放,质量压缩的方式将图片压缩到 100 k以内
public static Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = 1920f;// 这里设置高度为1920f
float ww = 1080f;// 这里设置宽度为1080f
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;// be=1表示不缩放
if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w hh) {// 如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
return bitmap;
}
3.2 将Bitmap保存到本地手机路径
public static void saveBitmap(Bitmap bitmap, File file) {
try {
FileOutputStream fos = new FileOutputStream(file);
// 这两保存的时候我选择了70的质量
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
fos.flush();
fos.close();
} catch (Exception e) {
PLog.e("saveBitmap err11 = ", e);
}
}
4.总结
开发一个项目的过程中,会遇到很多困难,中间会遇到各种各样的问题,会百度各种各种的问题,也会test各种方法,有用或没用,可以在旁边新建一个记事本,将用到的,可用的,方法记录下来,包括参考的博客地址,记录可以杂乱一点,但不影响。这样在项目结束之后,有了充足的时间,然后再去一点点整理,由浅及深,慢慢的去看这些博客,梳理成自己的知识。这样在下次遇到这些问题的时候,就会有一种我遇到过,我知道怎么解决,对于预言项目周期,以及自身成长都有不错的效果。
作者:HeartCircle