maven(2023最新版0.4.19)
<!-- 图片缩略图 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.19</version>
</dependency>
java工具类
/**
* 根据指定大小和指定精度压缩图片
*
* @param srcPath 源图片地址
* @param desPath 目标图片地址
* @param desFileSize 指定图片大小,单位kb
* @param accuracy 精度,递归压缩的比率,建议小于0.9
*/
public static void compressPicForScale(String srcPath, String desPath, long desFileSize, double accuracy) {
if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(srcPath)) {
return;
}
File srcFile = FileUtil.file(srcPath);
if (!srcFile.exists()) return;
if (accuracy <= 0) {
log.info("压缩系数太小");
return;
}
try {
long srcFileSize = srcFile.length();
log.info("源图片:" + srcPath + ",大小:" + srcFileSize / 1024 + "kb");
// 1、先转换成jpg
Thumbnails.of(srcPath).scale(1f).toFile(desPath);
// 2、递归压缩,直到目标文件大小小于desFileSize
compressPicCycle(desPath, desFileSize, accuracy);
// 3、完成
File desFile = FileUtil.file(desPath);
log.info("目标图片:" + desPath + ",大小" + desFile.length() / 1024 + "kb");
} catch (Exception e) {
log.error("目标图片:" + desPath + "==失败",e);
}
}
/**
* 压缩
*
* @param sourcePath 目标图片地址
* @param desFileSize 指定图片大小,单位kb
* @param accuracy 精度,递归压缩的比率,建议小于0.9
* @throws IOException
*/
private static void compressPicCycle(String sourcePath, long desFileSize, double accuracy) throws IOException {
if (accuracy >= 0.9) {
log.info("压缩系数太大{}", accuracy);
accuracy = 0.8;
}
File sourceFile = FileUtil.file(sourcePath);
long sourceFileSize = sourceFile.length();
//上下20%
double max = desFileSize * 1.2 * 1024, min = desFileSize * 0.8 * 1024;
if (sourceFileSize < min || (min < sourceFileSize && sourceFileSize < max)) {
return;
}
//最大
max = desFileSize * 2048;
if (sourceFileSize < max) {
accuracy = 0.85;
}
// 计算宽高
BufferedImage bim = ImageIO.read(sourceFile);
int bimWidth = bim.getWidth();
int bimHeight = bim.getHeight();
int desWidth = new BigDecimal(bimWidth).multiply(new BigDecimal(accuracy)).intValue();
int desHeight = new BigDecimal(bimHeight).multiply(new BigDecimal(accuracy)).intValue();
Thumbnails.of(sourcePath).size(desWidth, desHeight).outputQuality(accuracy).toFile(sourcePath);
//递归
compressPicCycle(sourcePath, desFileSize, accuracy);
}
我这里 指定大小 上下浮动20%就不处理。
目标地址和源地址可以填同一个