参考:

    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各种方法,有用或没用,可以在旁边新建一个记事本,将用到的,可用的,方法记录下来,包括参考的博客地址,记录可以杂乱一点,但不影响。这样在项目结束之后,有了充足的时间,然后再去一点点整理,由浅及深,慢慢的去看这些博客,梳理成自己的知识。这样在下次遇到这些问题的时候,就会有一种我遇到过,我知道怎么解决,对于预言项目周期,以及自身成长都有不错的效果。

更多相关文章

  1. Android(安卓)Kikat下由图片Uri获取Path的解决方案
  2. Android(安卓)图片剪切框架 uCrop 简单集成
  3. 解决listview设置背景图片以后,拖动出现黑色的问题。
  4. android xml文件中进行上传图片以及获取图片
  5. Android(安卓)自定义TextView实现宫格布局,Drawable添加图片并控
  6. 领略千变万化的Android(安卓)Drawable (一)
  7. Android——selector背景选择器
  8. Android解码/显示/播放Gif图片动画
  9. Android(安卓)Training Caching Bitmaps 翻译

随机推荐

  1. Android系统架构概况
  2. Robot Framework如何对Android的控件定位
  3. Android获取软键盘输入内容
  4. Android应用程序启动Binder线程源码分析
  5. 分享两本android电子书
  6. Android(安卓)Handler机制剖析
  7. Android实现XML解析技术
  8. 10.Android之测试代码实现步骤
  9. Simple Guide for Porting Android(安卓)
  10. 【Android】Android(安卓)4.0 无法接收开