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

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

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

通用裁图逻辑:

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

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);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • js 彻底理解回调函数「建议收藏」

    一、前奏在谈回调函数之前,先看下下面两段代码:不妨猜测一下代码的结果。functionsay(value){alert(value);}alert(say);alert(say(‘hijs.’));如果你测试了,就会发现:只写变量名say返回的将会是say方法本身,以字符串的形式表现出来。而在变量名后加()如say()返回的就会使say方法调用后的结果,这里

    2022年4月4日
    56
  • 曼昆 《经济学原理》(第5版)_曼昆经济学原理第几版好

    曼昆 《经济学原理》(第5版)_曼昆经济学原理第几版好第一章经济学十大原理在本章中你将——知道经济学研究稀缺性资源配置考察人们面临的一些交替关系知道机会成本的含义懂得在作出决策时如何运用边际推理讨论激励如何影响人们的行为考虑为什么人们或国家之间的交易可以使各方面受益-9经济学原理第五版 讨论为什么市场是一种良好的、但并不是完善的资源配置方式了解是什么因

    2022年9月19日
    2
  • Intellij IDEA神器居然还有这些小技巧

    概述 真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜。出于对 的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的 技巧分享给大家。本文是这个系列的第一篇,主要介绍一些你可能

    2022年3月13日
    73
  • C语言基础:函数的定义与调用[通俗易懂]

    C语言基础:函数的定义与调用[通俗易懂]    在前面内容中我们调用了一个标准C的库函数,叫printf,那么如果我们想自己定义函数应该如何来编写程序呢?定义函数又有什么好处呢?因为我们在教材中提及到的例子主要目的是为了让读者对程序的原理有一定的了解,所以设定的例子程序通常都比较简单,基本上在几行到十几行,多一点的也就三五十行代而已,但是在真正的编程工作中,我们需要完成的代码将非常大,所以将代码合理的分为不同的区块是很有必要的,…

    2022年6月30日
    33
  • Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 21 path $.data

    Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 21 path $.data

    2021年10月1日
    160
  • java pojo 是什么_POJO是什么,javabean是什么,以及POJO与javabean的区别

    java pojo 是什么_POJO是什么,javabean是什么,以及POJO与javabean的区别POJO(PlainOrdinaryJavaObject)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。使用POJO名称是为了避免和EJB混淆起来,而且简称比较直接.其中有一些属性及其gettersetter方法的类,没有业务逻辑,有时可以作为VO(value-object)或dto(DataTransformObject)来使用.当然,…

    2022年5月8日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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