关于安卓压缩图片

标签: android 压缩 图片
23人阅读 评论(0) 收藏 举报
分类:

遇坑过程

想保存Glide的缓存图片(失败)

一开始是想用Glide的硬盘缓存图片的,不过他计算的key值无法获取到(或许我不会),那就无法知道文件名字,这方法不行

自己用BitmapFactory压缩(忽大忽小)

上网看https://blog.csdn.net/jdsjlzx/article/details/44228935,用BitmapFactory压缩,效果是有些图片是尺寸是会变小,可是有些体积反而变大了(这也不太对)

下面是核心代码的使用demo

使用方法save(getimage(imagePath), Environment.getExternalStorageDirectory()+"/2.png", Bitmap.CompressFormat.PNG);


    /**
     * 图片按比例大小压缩方法
     *
     * @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 = 2560f;// 图片最大的高度为
        float ww = 1440f;// 图片最大的宽度为
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        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
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    /**
     * 保存图片
     *
     * @param src      源图片
     * @param filePath 要保存到的文件路径
     * @param format   格式
     * @return {@code true}: 成功<br>{@code false}: 失败
     */
    public static boolean save(Bitmap src, String filePath, Bitmap.CompressFormat format) throws IOException {
        return save(src, (new File(filePath)), format);
    }

    /**
     * 保存图片
     *
     * @param src    源图片
     * @param file   要保存到的文件
     * @param format 格式
     * @return {@code true}: 成功<br>{@code false}: 失败
     */
    public static boolean save(Bitmap src, File file, Bitmap.CompressFormat format) throws IOException {
        return save(src, file, format, false);
    }

    /**
     * 保存图片
     *
     * @param src      源图片
     * @param filePath 要保存到的文件路径
     * @param format   格式
     * @param recycle  是否回收
     * @return {@code true}: 成功<br>{@code false}: 失败
     */
    public static boolean save(Bitmap src, String filePath, Bitmap.CompressFormat format, boolean recycle) throws IOException {
        return save(src, (new File(filePath)), format, recycle);
    }

    /**
     * 保存图片
     *
     * @param src     源图片
     * @param file    要保存到的文件
     * @param format  格式
     * @param recycle 是否回收
     * @return {@code true}: 成功<br>{@code false}: 失败
     */
    public static boolean save(Bitmap src, File file, Bitmap.CompressFormat format, boolean recycle) throws IOException {
        if (isEmptyBitmap(src) || file.exists()) return false;
        System.out.println(src.getWidth() + ", " + src.getHeight());
        OutputStream os = null;
        boolean res = false;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file));
            res = src.compress(format, 100, os);
            if (recycle && !src.isRecycled()) src.recycle();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            os.close();
        }
        return res;
    }

    /**
     * 判断bitmap对象是否为空
     *
     * @param src 源图片
     * @return {@code true}: 是<br>{@code false}: 否
     */
    private static boolean isEmptyBitmap(Bitmap src) {
        return src == null || src.getWidth() == 0 || src.getHeight() == 0;
    }

最后Luban完美解决

最后看到https://github.com/Curzibn/Luban/blob/master/README.md,使用Luban压缩,可以完美解决问题

Luban.with(this)
                    .load(path1)                                   // 传人要压缩的图片列表
                    .ignoreBy(100)                                  // 忽略不压缩图片的大小
                    .setTargetDir(Environment.getExternalStorageDirectory()+"/aaaaa")                        // 设置压缩后文件存储位置
                    .setCompressListener(new OnCompressListener() { //设置回调
                        @Override
                        public void onStart() {
                            // TODO 压缩开始前调用,可以在方法内启动 loading UI
                        }

                        @Override
                        public void onSuccess(File file) {
                            // TODO 压缩成功后调用,返回压缩后的图片文件
                            Log.d(TAG, "onSuccess: "+file.exists());
                        }

                        @Override
                        public void onError(Throwable e) {
                            // TODO 当压缩过程出现问题时调用
                            Log.d(TAG, "onError: "+e);
                        }
                    }).launch();    //启动压缩

总结

因为以前也没想过与研究压缩图片的事情,一开始时候一直想的事情是控制图片尺寸,最后发现尺寸一样的图片,人看上去也一样的图片,而大小可能相差很大。

查看评论

Android一种高效压缩图片的方法

公司项目中有一个功能,就是用户能够上传图片到我们的服务器中,图片可以是用户本地图片,也可以是用户拍摄的照片。这些图片不受我们控制,有些照片可能很大,比如手机相机拍摄的,大小都是几兆的,用户直接上传这么...
  • xiaoli100861
  • xiaoli100861
  • 2016-02-19 11:58:21
  • 1258

libjpeg哈夫曼算法压缩图片

之前的博客提到过关于图片压缩的方法: Android 图片压缩,Bitmap优化 Android原生的压缩方法,不在乎两种:通过设置simpleSize根据图片尺寸压缩图片;通过Bi...
  • B1ueKid
  • B1ueKid
  • 2017-04-24 22:49:09
  • 594

安卓中两种压缩图片详解(比例压缩与质量压缩)

在提图片压缩之前,我先总结下图片的三种常见格式:JPEG,JPG,PNG  Jpeg格式   与jpg格式相似,经常在拷相片的时候看到得,但我们制作图片的时候一般是保存jpg,该种图片格式是文件相...
  • startCrazyActivity
  • startCrazyActivity
  • 2016-09-11 17:45:50
  • 1542

安卓压缩图片

  • 2013年05月24日 18:14
  • 2KB
  • 下载

安卓图片压缩处理的终极方法,适用于各种机型

//直接调用getimage,参数为:路径、宽、高 public static Bitmap getimage(String pathName, int reqWidth, int reqHei...
  • qq_34698126
  • qq_34698126
  • 2017-03-19 16:36:08
  • 406

android图片压缩的三种方式

为了避免oom的出现,几乎每个应用都会对大图进行压缩,我现在手头做的产品就有很多地方用到,以前封装工具类的时候,都是在网上找东找西,然后拼拼凑凑,有效果就行了,一直用的迷迷糊糊,这几天工作比较闲,正好...
  • u011172283
  • u011172283
  • 2016-02-24 13:43:18
  • 5705

android 图片压缩 demo

  • 2012年12月03日 19:28
  • 3.23MB
  • 下载

图片压缩兼容安卓和苹果的js插件

  • 2016年09月30日 10:25
  • 9KB
  • 下载

Android:图片压缩类ThumbnailUtils

从Android 2.2开始系统新增了一个缩略图ThumbnailUtils类,位于framework的android.media.ThumbnailUtils位置,可以帮助我们从mediaprovi...
  • HMYANG314
  • HMYANG314
  • 2014-08-03 17:32:17
  • 950

Android 图片压缩实现过程代码

Android图片压缩非两种,一种质量压缩,一种像素压缩,前者多用于图片上传时,后者多用于本地图片展示缩略图时。总结并记录一下,方便以后使用。 具体的分析可以参考这篇文章,http://www.co...
  • Siobhan
  • Siobhan
  • 2016-02-19 17:31:09
  • 1561
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 1271
    排名: 4万+