前言
最近有个新需求,项目中对客户上传jpg图片的时候,每次都是校验大小必须≤30KB,但是客户实际使用的时候,总是会自己去进行压缩,压缩到30KB以内之后再上传,使用时间长了之后,客户总会觉得很麻烦,于是乎,希望上传的jpg图片由系统自动进行压缩到30KB以内。
想了想,如果由系统进行压缩,那么一次压缩之后就一定会到了30KB以内了吗?我的想法是进行递归压缩,每次压缩完了判断jpg图片大小,如果30KB以内了,就可以了,不然继续递归压缩。
如果你在看这个文章,希望有更好的方式评论一下,让我也学习学习,谢谢。
代码示例
代码很简单,注释说明结合,理解很简单
@RequestMapping(value = "/file/uplaod", method = RequestMethod.POST)
public String uploadPoster(@RequestParam("file") MultipartFile file) throws Exception {
// 上传的jpg图片文件名, 不管压缩还是不压缩, 都要保证最后文件的名称就是originalFilename
final String originalFilename = file.getOriginalFilename();
// 文件大小 && 转KB
long size = file.getSize();
int sizeKb = (int) ((size / 1024) + 1);
log.info("上传文件:{}, 大小是:{}KB", originalFilename, sizeKb);
// 目标文件
File targetFile = new File("D://", originalFilename);
// 不管上传的图片大小, 先上传上去, 在判断大小或压缩
file.transferTo(targetFile);
if (sizeKb > 30) {
// 文件递归压缩的时候, 过程中文件名称变化的标识
int identity = 0;
// 压缩
while (sizeKb > 30) {
identity++;
// 上一次的目标文件, 作为本次压缩的源文件
String fileName = targetFile.getName();
final File sourceFile = new File("D://", fileName);
// 目标文件, SystemYs 和 变量identity 都是每次压缩文件重命名的格式
// 测试过,同一个文件不能自己对自己进行压缩,所以进行重命名
String targetFileName = "SystemYs" + identity + "-" + originalFilename;
targetFile = new File("D://", targetFileName);
// 源文件IO流
final InputStream in = new FileInputStream(sourceFile);
// 目标文件IO流
final OutputStream out = new FileOutputStream(targetFile);
// 压缩(Hutool工具类,三个参数说明看API即可,很简单)
ImgUtil.scale(in, out, 0.7f);
// 关闭流
out.close();
in.close();
// 压缩完了之后, 删除源文件
sourceFile.delete();
size = targetFile.length();
sizeKb = (int) ((size / 1024) + 1);
log.info("递归压缩, 压缩之后文件:{}, 大小:{}KB", fileName, sizeKb);
}
// 递归压缩后, 图片<=30KB了, 进行文件重命名
targetFile.renameTo(new File("D://", originalFilename));
}
return "OK";
}