图片压缩算法「建议收藏」

图片压缩算法「建议收藏」图片压缩算法

大家好,又见面了,我是你们的朋友全栈君。

通用裁图逻辑:

第一:我们先看下质量压缩方法:

private Bitmap compressImage(Bitmap image) {  
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    //质量压缩方法,这里100表示不压缩,把压缩后的数据存入baos中 
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    int options = 100;  
    while ( baos.size() / 1024>100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩 
        baos.reset();//重置baos即清空baos 
        image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 
        options -= 10;//每次都减少10 
    }  
    //把压缩后的数据baos存放到ByteArrayInputStream中 
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
    //把ByteArrayInputStream数据生成图片 
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
    return bitmap;  
}  

第二:图片按比例大小压缩方法(根据路径获取图片并压缩):

private Bitmap getimage(String srcPath) {  
    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    //开始读入图片,把options.inJustDecodeBounds 设回true了 
    newOpts.inJustDecodeBounds = true;  
    //此时返回bm为空 
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);
    newOpts.inJustDecodeBounds = false;  
    int w = newOpts.outWidth;  
    int h = newOpts.outHeight;  
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 
    float hh = 800f;//这里设置高度为800f 
    float ww = 480f;//这里设置宽度为480f 
    //缩放比,当前固定比例缩放,只用高或者宽其中一个数据计算即可 
    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);//压缩比例后进行质量压缩 
}  

第三:图片按比例大小压缩方法(根据Bitmap图片压缩):

private Bitmap comp(Bitmap image) {  
      
    ByteArrayOutputStream baos = new ByteArrayOutputStream();         
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
    //判断如果图片大于1M,进行压缩避免在生成图片时溢出 
    if( bass.size() / 1024>1024) {   
        baos.reset();    //重置baos即清空baos 
        image.compress(Bitmap.CompressFormat.JPEG, 50, baos);   //这里压缩50%,把压缩后的数据存放到baos中 
    }  
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    //开始读入图片,把options.inJustDecodeBounds 设回true了 
    newOpts.inJustDecodeBounds = true;  
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    newOpts.inJustDecodeBounds = false;  
    int w = newOpts.outWidth;  
    int h = newOpts.outHeight;  
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 
    float hh = 800f;//这里设置高度为800f 
    float ww = 480f;//这里设置宽度为480f 
    //缩放比,当前固定比例缩放,只用高或者宽其中一个数据计算即可 
    int be = 1;   //be=1表示不缩放 
    // 如果宽度大的话根据宽度固定大小缩放 
    if (w > h && w > ww) {
        be = (int) (newOpts.outWidth / ww);  
    //如果高度高的话根据宽度固定大小缩放 z 
    } else if (w < h && h > hh) {
        be = (int) (newOpts.outHeight / hh);  
    }  
    if (be <= 0)  
        be = 1;  
    newOpts.inSampleSize = be;//设置缩放比例 
    //重新读入图片,把options.inJustDecodeBounds设回false了 
    isBm = new ByteArrayInputStream(baos.toByteArray());  
    bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    return compressImage(bitmap);//压缩比例后进行质量压缩 
}  

常用简单方法:

  • 上面的几种方法是以字节流的方式裁剪图片。现在,再来看一种简单的裁剪方法,这个裁剪方法是通过Bitmap的创建功能来截取原图的部分数据:
 /** 图片裁剪:按指定大小裁剪 */
public Bitmap tailorImageByImgs(String srcPath, int hh, int ww) {
    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath);

    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    int retX = w > ww ? (w - ww) / 2 : 0;//基于原图,取正方形左上角x坐标
    int retY = h > hh ? (h - hh) / 2 : 0;

    //下面这句是关键
    return Bitmap.createBitmap(bitmap, retX, retY, hh, ww, null, false);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150562.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 有java安装包怎么安装(java安装包打不开)

    JavaJDK安装包获取和安装:JDK1.8.211官网下载地址https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html注意:1.不要安装到C盘2.安装路径中不要出现任何的中文环境变量配置:Windows+E–>页面空白处鼠标右键–>属性系统页面…

  • ORACLE 查询字表未明确定义列「建议收藏」

    ORACLE 查询字表未明确定义列「建议收藏」运行环境:Oracle10gsqlplus环境下。 在查询语句中,经常会出现一个错误: SQL基础:ORA-00918:未明确定义列的错误。 当前遇到有两种情况。原因为:当查询语句中,查询的表(数据集)中有相同的字段名,查询字段无法确认是改查那个字段 时,就会报未明确定义列的错误。 第一种情况: 1.单表时: 比如fconsign表中存在三个字段:fcsg_c

  • 适配器模式(Adapter模式)详解

    适配器模式(Adapter模式)详解http://c.biancheng.net/view/1361.html在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,讲中文的人同讲英文的人对话时需要一个翻译,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的SD内存卡时需要一个读卡器等。在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。

  • 从头开始学MySQL——-存储过程与存储函数(1)

    从头开始学MySQL——-存储过程与存储函数(1)10.1.1创建存储过程存储过程就是一条或者多条SQL语句的集合,可以视为批文件。它可以定义批量插入的语句,也可以定义一个接收不同条件的SQL。创建存储过程的语句为CREATEPROCEDURE,创建存储函数的语句为CREATEFUNCTION。调用存储过程的语句为CALL。调用存储函数的形式就像调用MyS……

  • ACTION_NAME等常量 不能在模板里直接取值?

    ACTION_NAME等常量 不能在模板里直接取值?

  • PHP中include()与require()的区别说明

    PHP中include()与require()的区别说明

    2021年10月14日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号