Java使用Thumbnails实现图片指定大小压缩

项目中有个要求,对上传服务器的图片大小进行判断,大于50k的图片要进行压缩处理,让其小于50k后在上传。针对图片压缩,一般有以下两种方法:1)java api的ImageIO实现图片压缩,但效果不好,图片压缩后出现变红现象,看了网上的博客普遍都说bug比较多,会有OOM内存溢出的现象。2)该方法使用的是谷歌的Thumbnails插件来实现图片压缩。本文主要介绍的是使用插件实现图片压缩。

实现:

Thumbnails.of("源文件路径") .scale(1f) //0-1 float 压缩大小.outputQuality(0.7f) //0-1 压缩质量.toFile("新文件路径");

需要引入的依赖:

<!--图片压缩--><dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency>

使用Thumbnails插件实现图片压缩方法有以下两种实现方式:

第一种方式,实现思路:

按照一定的比例压缩图片,递归压缩图片,如果压缩后的图片还不满足要求,则继续进行压缩,直到压缩后的图片大小满足要求。

代码实现:

public class ThumbnailUtil {/*** 根据指定大小和指定经度压缩图片** @param srcPath     源图片地址* @param desPath     目标图片地址* @param desFileSize 指定图片大小,单位kb* @param accuracy    精度,递归压缩的比率,建议小于0.9* @return*/public static String compressPictureForScale(String srcPath, String desPath, long desFileSize, double accuracy) {if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(desPath)) {return null;}if (!new File(srcPath).exists()) {return null;}try {File srcFile = new File(srcPath);long srcFileSize = srcFile.length();System.out.println("源图片: " + srcPath + ", 大小: " + srcFileSize / 1024 + "kb");//1.先转换成jpgThumbnails.of(srcPath).scale(1f).toFile(desPath);//递归压缩,直到目标文件大小小于desFileSizecompressPicCycle(desPath, desFileSize, accuracy);File desFile = new File(desPath);System.out.println("目标图片: " + desPath + ", 大小: " + desFile.length() / 1024 + "kb");System.out.println("图片压缩完成!");} catch (Exception e) {e.printStackTrace();return null;}return desPath;}private static void compressPicCycle(String desPath, long desFileSize, double accuracy) throws IOException {File srcFileJPG = new File(desPath);long srcFileSizeJPG = srcFileJPG.length();//2.判断大小,如果小于50kb,不用压缩,如果大于等于50kb,需要压缩if (srcFileSizeJPG <= desFileSize * 1024) {return;}//计算宽高BufferedImage bim = ImageIO.read(srcFileJPG);int srcWidth = bim.getWidth();int srcHeight = bim.getHeight();int destWidth = new BigDecimal(srcWidth).multiply(new BigDecimal(accuracy)).intValue();int destHeight = new BigDecimal(srcHeight).multiply(new BigDecimal(accuracy)).intValue();Thumbnails.of(desPath).size(destWidth,destHeight).outputQuality(accuracy).toFile(desPath);compressPicCycle(desPath,desFileSize,accuracy);}public static void main(String[] args) {String srcPath = "C:\\Users\\hemanman6\\Desktop\\微信图片_20210802151348.png";String desPath = "C:\\Users\\hemanman6\\Desktop\\2.jpg";ThumbnailUtil.compressPictureForScale(srcPath,desPath,50,0.8);}
}

结果显示:


注意

png转jpg图片占存大小变小,jgp转png图片占存大小变大

为了更贴近公司的业务代码,对上述代码进行改进,去除了一些多余的IO过程,把递归改成了循环,并且把文件操作改为了流和字节数组的操作。

第二种,使用循环方式、流、字节数组实现

代码实现如下:

public class ThumbnailUtis1 {private static Logger logger = LoggerFactory.getLogger(ThumbnailUtis1.class);/*** 根据指定大小压缩图片** @param imageBytes  源图片字节数组* @param desFileSize 指定图片大小,单位kb* @param imageId     影像编号* @return 压缩质量后的图片字节数组*/public static byte[] compressPictureForScale(byte[] imageBytes, long desFileSize, String imageId) {if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {return imageBytes;}long srcSize = imageBytes.length;double accuracy = getAccuracy(srcSize / 1024);try {while (imageBytes.length > desFileSize * 1024) {ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);Thumbnails.of(inputStream).scale(accuracy).outputQuality(accuracy).toOutputStream(outputStream);imageBytes = outputStream.toByteArray();}logger.info("【图片压缩】imageId={} | 图片原大小={}kb | 压缩后大小={}kb", imageId, srcSize / 1024,imageBytes.length / 1024);} catch (Exception e) {logger.error("【图片压缩】msg=图片压缩失败!", e);}return imageBytes;}/*** 自动调节精度(经验数值)** @param size 源图片大小* @return 图片压缩质量比*/private static double getAccuracy(long size) {double accuracy;if (size < 900) {accuracy = 0.85;} else if (size < 2047) {accuracy = 0.6;} else if (size < 3275) {accuracy = 0.44;} else {accuracy = 0.4;}return accuracy;}public static void main(String[] args) throws IOException {//将文件内容读入字节数组。文件始终处于关闭状态。byte[] bytes = FileUtils.readFileToByteArray(new File("C:\\Users\\hemanman6\\Desktop\\微信图片_20210802151348.jpg"));long l = System.currentTimeMillis();bytes = ThumbnailUtis1.compressPictureForScale(bytes,30,"x");System.out.println(System.currentTimeMillis()-1);//将字节数组写入到文件FileUtils.writeByteArrayToFile(new File("C:\\Users\\hemanman6\\Desktop\\333.jpg"),bytes);}
}

其中,FileUtils类需要引入如下依赖:

<!-- https://mvnrepository.com/artifact/commons-io/commons-io --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>

结果显示:


Java使用Thumbnails实现图片指定大小压缩相关推荐

  1. 通过google插件Thumbnails实现图片指定大小压缩

    前言: 1.由于商户进件时,上游对图片大小有要求(500kb以下),而我们平台图片过大(10M以上),所以必须通过程序将图片压缩后再上传: 2.java api可以通过ImageIO实现图片压缩,但效 ...

  2. 怎么把照片缩小到200k?图片指定大小压缩怎么弄?

    平时在给账号设置头像时,都会遇到图片过大无法上传的情况,这时候我们可以通过图片压缩指定大小工具来将图片压缩到200kb以下,这样就可以顺利设置头像了,下面一起来看一下图片指定大小压缩(https:// ...

  3. vue 图片指定大小压缩

    1.安装命令npm i image-conversion --save 2.引入插件 import * as imageConversion from "image-conversion&q ...

  4. JAVA根据指定大小压缩图片

    /*** 根据指定大小压缩图片** @param sourceFilePath 源图片路径 + 文件名(例 "D:\\image\\aa.jpg")* @param outFile ...

  5. object-fit 解决图片指定大小被压缩问题

    object-fit 解决图片指定大小被压缩问题 第一次遇到这个属性,是在给video 写 poster的时候,选取的作为poster的img的尺寸有点小,导致video播放器两边有留白.在控制台查看 ...

  6. C# 图片压缩(指定大小压缩和指定尺寸压缩)

    一按大小压缩测试代码: 一测试效果: 一主要代码: /// <summary>/// 压缩图片至200 Kb以下/// </summary>/// <param name ...

  7. 将图片压缩至指定大小Kb(Thumbnailator)

    放代码前,先唠叨唠叨,舒缓一下我的郁闷之情. 今天下午改一个后台管理系统的需求,要求上传的图片要压缩到300kb,感觉不难,就开搞. 先撩拨一下度娘,搞点货出来瞅瞅,不复杂就干脆搬砖算了. 嗯,度娘不 ...

  8. java 压缩图片至指定大小

    需求: 压缩图片至300k以下 一开始没有思路在网上搜,发现google有个插件叫Thumbnails,然后看到了这篇文章: https://blog.csdn.net/u010355502/arti ...

  9. java jsoup抓取百度图片保存到本地,并压缩到指定大小(可指定宽高或者流大小)

    代码如下: package cn.xyz.commons.utils; import java.awt.image.BufferedImage; import java.io.ByteArrayInp ...

  10. linux下的c语言mysql编程,详解java google Thumbnails 图片处理

    在后端开发的过程中,都逃不开与文件传输特别是图片的传输打交道,但是因为现在各种拍照设备发展越来越快,拍出的照片更是越来越清晰,但是照片文件的大小也是越来越大了,手机拍照小则2M大则30M这在网络传输过 ...

最新文章

  1. 《算法竞赛中的初等数论》(四)正文 0x40反演(ACM / OI / MO)(十五万字符数论书)
  2. 百分点首席经济学家张忠解读《美国白宫大数据白皮书》
  3. Pandas简明教程:七、Pandas缺失数据的处理(数据清洗基础)
  4. 下面关于“栈”的描述,正确的是( )
  5. windows 2012 如何设置取消禁拼ping
  6. android 中resources管理
  7. 控件ListView相关属性 1217
  8. 利用Excel批量高速发送电子邮件
  9. iPhone 13 Pro手机壳曝光 网友:更丑了
  10. python-同步(互斥)锁、递归锁、同步条件(event)
  11. 2013再见,2014你好!
  12. 如何解决”ArcGIS Server Site is currently being configured by another administrative operation“的问题
  13. 汇编语言---计算绝对值
  14. BZOJ 3224: Tyvj 1728 普通平衡树(替罪羊树)
  15. Python——动画精灵
  16. 外企8年,我学到的人性化,不止是宽容
  17. CF1367C - Social Distance
  18. android auto note 8,可持续发展BMW将发布无线安卓互联系统,CarPlay终于不再一家独大!...
  19. unity让特效在UI上播放
  20. 设计模式(八):装饰模式

热门文章

  1. Power BI集成Power Apps,轻松实现用户在报告中任意输入信息
  2. vue中组件根元素添加样式无效
  3. 信息最全--MySQL循环插入测试用户数据--姓名
  4. 一般纳税人税额计算_一般纳税人应纳税额如何计算?
  5. SQL_Xbar代码
  6. linux免安装mysql_Linux 配置mysql 免安装版。
  7. ascii码所有字符对照表(包含汉字和外国文字)
  8. 【uniapp公众号分销商城从0到1】手机验证注册登录(04)
  9. 对接企业微信3:网页授权登录
  10. 我们无法更新系统保留的分区_什么是系统保留分区,您可以删除它吗?(Windows10 科普)2020...