1 序言
调第三方平台,太贵。还得自己有,才是真。
2 Maven 依赖
<!--图片压缩-->
<!--https://repo1.maven.org/maven2/net/coobird/thumbnailator/-->
<!--Java使用Thumbnails实现图片指定大小压缩-CSDN-https://blog.csdn.net/qq_38530648/article/details/119333058-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
3 示例代码
//1.先转换成jpg
Thumbnails.of(srcPath) // File / URL / InputStream / BufferedImage /
.scale(scale)
.outputQuality(quality)
.toFile(desPath);
import jdk.management.resource.ResourceType;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author johnny-zen
* @version v1.0
* @description ...
* @refrence-doc
* [1] Java使用Thumbnails实现图片指定大小压缩 - CSDN - https://blog.csdn.net/qq_38530648/article/details/119333058
* @gpt-promt
*/
public class ThumbnailUtil {
private final static Logger logger = LoggerFactory.getLogger(ThumbnailUtil.class);
/**
* 根据指定大小和指定经度压缩图片
*
* @param srcPath 源图片地址
* @param desPath 目标图片地址
* @param desFileSize 指定图片大小,单位kb
* @param scale 精度,递归压缩的比率,建议小于0.9
* @return
*/
public static String compressPictureForScale(String srcPath, String desPath, long desFileSize, double scale,double quality, int compressCount) {
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();
logger.info(String.format("source file : %s, size : %d kb", srcPath, srcFileSize / 1024 ));
//1.先转换成jpg
Thumbnails.of(srcPath) // File / URL / InputStream / BufferedImage /
.scale(scale)
.outputQuality(quality)
.toFile(desPath);
//递归压缩,直到目标文件大小小于desFileSize
//compressPicCycle(desPath, desFileSize, accuracy, compressCount);
File desFile = new File(desPath);
logger.info(String.format("Success to complete file compression ! | destination file : %s, size : %d kb", desPath, (int) (desFile.length() / 1024) ));
} catch (Exception e) {
e.printStackTrace();
return null;
}
return desPath;
}
private static void compressPicCycle(String desPath, long desFileSize, double accuracy, int compressCount) throws IOException {
File srcFileJPG = new File(desPath);
long srcFileSizeJPG = srcFileJPG.length();
//2.判断大小,如果小于50kb,不用压缩,如果大于等于50kb,需要压缩
if (srcFileSizeJPG <= desFileSize * 1024) {
logger.debug(String.format("File size is is less than %d kb, no compression optimization required.", desFileSize));
return;
} else {
logger.info(String.format("%d | source file : %s, size : %d kb", compressCount, desPath, desFileSize / 1024 ));
}
//计算宽高
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);
// Thumbnails.of(targetFile)
// .scale(0.1f)//指定图片大小 0-1f 1f是原图
// .outputQuality(1f)//图片质量 0-1f 1f是原图
// .toFile(newFile);
File file = new File(desPath);
long desPathFileSize = file.length();
compressPicCycle(desPath, desPathFileSize,accuracy, compressCount + 1);
}
private Map<String, Object> saveFileAndThumbnail(MultipartFile file) throws BusinessException {
String fileUploadPath = "C:\\Users\\408675\\Desktop\\";
// 判断文件是否为空
if (!file.isEmpty()) {
String root = fileUploadPath;//上传路径
String picturePath = fileUploadPath;//保存路径
String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
String newName = String.valueOf((new Date()).getTime()) + ext;
File filedict = new File(root+picturePath);
if(!filedict.exists()){
filedict.mkdirs();
}
File targetFile=new File(root+picturePath+File.separator+newName);
File newFile=new File(root+picturePath+File.separator+"s"+newName);
try {
file.transferTo(targetFile);
Thumbnails.of(targetFile)
.scale(0.1f)//指定图片大小 0-1f 1f是原图
.outputQuality(1f)//图片质量 0-1f 1f是原图
.toFile(newFile);
BufferedImage bimg = ImageIO.read(targetFile);
int width = bimg.getWidth();
int height = bimg.getHeight();
BufferedImage thumbnail = ImageIO.read(newFile);
int thumbnailWidth = thumbnail.getWidth();
int thumbnailHeight = thumbnail.getHeight();
Map<String, Object> map = new HashMap<String, Object>();
map.put("pictureHeight",height);
map.put("pictureWidth",width);
map.put("picturePath",picturePath+"/"+newName);
map.put("thumbnailHeight",thumbnailHeight);
map.put("thumbnailWidth",thumbnailWidth);
map.put("thumbnailPath",picturePath+"/s"+newName);
return map;
} catch (IllegalStateException e) {
e.printStackTrace();
throw new BusinessException("Fail to upload file! ");
} catch (IOException e) {
e.printStackTrace();
throw new BusinessException("图片上传失败");
} catch (Exception e) {
e.printStackTrace();
throw new BusinessException("图片上传失败");
}
}
return null;
}
public static void main(String[] args) {
Integer expectFileSize = 200;//200KB
Double scale = 1.0;
Double quality = 0.1;
String srcPath = "C:\\Users\\xxxx\\Desktop\\pics\\grape.jpg";
String coreFilename = srcPath.substring(0, srcPath.lastIndexOf("."));
String format = srcPath.substring(srcPath.lastIndexOf(".")+1);
String desPath = String.format("%s-%1.1f-%1.1f.%s", coreFilename, scale, quality, format);
ThumbnailUtil.compressPictureForScale(srcPath,desPath,expectFileSize, scale,quality, 0);
}
}