Android(安卓)图片压缩并保存的方法
参考:
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以内
/** * 图片按比例大小压缩方法 * * @param srcPath (根据路径获取图片并压缩) * @return */ 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 < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// 设置缩放比例 // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩 } /** * 质量压缩方法 * * @param image * @return */ public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 90; while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset(); // 重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中 options -= 10;// 每次都减少10 if (options < 0) { break; } } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片 return bitmap; }
3.2 将Bitmap保存到本地手机路径
/** * 保存Bitmap到指定文件 * @param bitmap 需要保存的图片 * @param file 保存的文件路径 */ 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各种方法,有用或没用,可以在旁边新建一个记事本,将用到的,可用的,方法记录下来,包括参考的博客地址,记录可以杂乱一点,但不影响。这样在项目结束之后,有了充足的时间,然后再去一点点整理,由浅及深,慢慢的去看这些博客,梳理成自己的知识。这样在下次遇到这些问题的时候,就会有一种我遇到过,我知道怎么解决,对于预言项目周期,以及自身成长都有不错的效果。
更多相关文章
- Android(安卓)Kikat下由图片Uri获取Path的解决方案
- Android(安卓)图片剪切框架 uCrop 简单集成
- 解决listview设置背景图片以后,拖动出现黑色的问题。
- android xml文件中进行上传图片以及获取图片
- Android(安卓)自定义TextView实现宫格布局,Drawable添加图片并控
- 领略千变万化的Android(安卓)Drawable (一)
- Android——selector背景选择器
- Android解码/显示/播放Gif图片动画
- Android(安卓)Training Caching Bitmaps 翻译