热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android三种常见的图片压缩方式

在开发中,我们经常有这样一种需求,从相册选择图片,上传到服务器。随着手机像素的不断提升,照片也是小一点的3,4兆,大一点的多大10多兆。如果直接上传原图,会增大服务器压力,所以,在上传之前对图片压缩就显得很必要了。

下面就为大家带来3种比较常见的压缩方式

先给出一组数据

原图:width:2976; height:2976
原图实际:--->byte:2299820 Mb:2.19328
质量压缩 size--->:byte:1599831 kb:1562.33496
按比例压缩 size--->:byte:191707 kb:187.21387
鲁班压缩 size--->:byte:143792 kb:140.42188

压缩效果:鲁班压缩 > 按比例压缩 > 质量压缩

1、质量压缩

 public void getBitmap(String imgPath, String outPath) {  
        BitmapFactory.Options newOpts = new BitmapFactory.Options();  
        newOpts.inJustDecodeBounds = false;  
        newOpts.inPurgeable = true;  
        newOpts.inInputShareable = true;  
        // Do not compress  
        newOpts.inSampleSize = 1;  
        newOpts.inPreferredCOnfig= Config.RGB_565;  
        storeImage(bitmap, outPath); //保存图片
    }

注意

  • 质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的,这也是为什么该方法叫质量压缩方法。所以这种方法,很可能不会减少图片的大小
  • 如果是bit.compress(CompressFormat.PNG, quality, baos);这样的png格式,quality就没有作用了,bytes.length不会变化,因为png图片是无损的,不能进行压缩

保存图片

/**
     * 把bitmap转化成图片存储在本地
     *
     * @param bitmap
     * @param outPath 本地的存储路径
     * @throws FileNotFoundException
     */
    public static boolean storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {
        FileOutputStream os = new FileOutputStream(outPath);
        boolean compressResult = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
        return compressResult;
    }

2、按比例压缩(尺寸压缩、采样率压缩)

/**
     * 按比例压缩
     *
     * @param path    原图片路径
     * @param targetW 压缩后宽度
     * @param targetH 压缩后高度
     * @return 压缩后的图片的保存路径
     */
    public static String compressScale(String path,, String outPath, int targetW, int targetH) throws FileNotFoundException {
        // 获取option  
        BitmapFactory.Options optiOns= new BitmapFactory.Options();
        // inJustDecodeBounds设置为true,这样使用该option decode出来的Bitmap是null,  
        // 只是把长宽存放到option中  
        options.inJustDecodeBounds = true;
        // 此时bitmap为null  
        Bitmap bitmap = BitmapFactory.decodeFile(path, options);
        int inSampleSize = 1; // 1是不缩放  
        // 计算宽高缩放比例  
        int inSampleSizeW = options.outWidth / targetW;
        int inSampleSizeH = options.outHeight / targetH;
        // 最终取大的那个为缩放比例,这样才能适配,例如宽缩放3倍才能适配屏幕,而  
        // 高不缩放就可以,那样的话如果按高缩放,宽在屏幕内就显示不下了  
        if (inSampleSizeW > inSampleSizeH) {
            inSampleSize = inSampleSizeW;
        } else {
            inSampleSize = inSampleSizeH;
        }
        // 一定要记得将inJustDecodeBounds设为false,否则Bitmap为null  
        options.inJustDecodeBounds = false;
        // 设置缩放比例(采样率)  
        options.inSampleSize = inSampleSize;
        bitmap = BitmapFactory.decodeFile(path, options);
        boolean isSuccess = storeImage(bitmap, outPath);
        if (isSuccess) {
            return outPath;
        }
        return "";
    }

这种方法是设置图片的采样率,降低图片像素,通过缩放图片像素来减少图片大小。

那么我又是如何来获取图片压缩前后的大小的呢?

注意:这里的图片的大小是指图片的实际大小,不是bitmap在内存中所占的大小,看压缩效果,就得看图片在文件中所占的大小。

/**
     * 获取本地文件大小
     *
     * @param imgPath 图片的路径
     * @return 图片实际的大小,单位byte
     */
    public static int getFileSize(String imgPath) {
        int size = 0;
        try {
            FileInputStream fis = new FileInputStream(new File(imgPath));
            size = fis.available();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return size;
    }

3、鲁班压缩(推荐)

鲁班压缩是根据一种算法得出来的,压缩效果基本上和微信一致,差不多在200k以内,图片不失真。

鲁班压缩:
https://github.com/Curzibn/Luban

build.gradle添加依赖

compile 'top.zibin:Luban:1.1.3'
private void lunBanPress(String path) {
        String pressPath = Environment.getExternalStorageDirectory().getPath();
        Luban.with(this)
                .load(path)                                   // 传人要压缩的图片列表
                .ignoreBy(100)                                  // 忽略不压缩图片的大小
                .setTargetDir(pressPath)                        // 设置压缩后文件存储位置
                .setCompressListener(new OnCompressListener() { //设置回调
                    @Override
                    public void onStart() {
                        // TODO 压缩开始前调用,可以在方法内启动 loading UI
                        Log.i(TAG, "onStart:开始鲁班压缩 ");
                    }

                    @Override
                    public void onSuccess(File file) {
                        // TODO 压缩成功后调用,返回压缩后的图片文件
                        Glide.with(activity).load(file).into(iv2);
                        Log.i(TAG, "onSuccess: 鲁班压缩成功 :");
                        try {
                            int size = new FileInputStream(file).available();
                            Log.i("tag", "鲁班压缩 size--->:" + "byte:" + size + "    kb:"
                                    + (float) size / 1024);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

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

源码地址:
https://github.com/zhouxu88/ImgCompress

到这里就结束啦~

以上就是Android三种常见的图片压缩方式的详细内容,更多关于Android 图片压缩的资料请关注其它相关文章!


推荐阅读
  • 深入解析:手把手教你构建决策树算法
    本文详细介绍了机器学习中广泛应用的决策树算法,通过天气数据集的实例演示了ID3和CART算法的手动推导过程。文章长度约2000字,建议阅读时间5分钟。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 本文基于对相关论文和开源代码的研究,详细介绍了LOAM(激光雷达里程计与建图)的工作原理,并对其关键技术进行了分析。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文介绍如何使用 Sortable.js 库实现元素的拖拽和位置交换功能。Sortable.js 是一个轻量级、无依赖的 JavaScript 库,支持拖拽排序、动画效果和多种插件扩展。通过简单的配置和事件处理,可以轻松实现复杂的功能。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
author-avatar
快乐星期八2012_846
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有