maven
<!--图片压缩-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version> <!-- 使用最新版本 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
java
package com.sun.basic.newImgName.utils;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class FileUtil {
/**
* BufferedImage转MultipartFile
*/
public static MultipartFile convert(BufferedImage bufferedImage, String fileName, String contentType) throws IOException {
// 将BufferedImage写入到字节数组输出流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", baos); // 假设你正在写入一个JPEG文件
byte[] fileContent = baos.toByteArray();
return ByteToMultipartFile(fileContent, fileName, contentType);
}
/** byte 转 BufferedImage转MultipartFile **/
public static MultipartFile ByteToMultipartFile(byte[] bytes, String fileName, String contentType) throws IOException {
MultipartFile multipartFile = new MockMultipartFile(
fileName, // 原始文件名
fileName, // 存储时的文件名
contentType, // 文件内容类型
bytes // 文件内容
);
return multipartFile;
}
/** 图片递归压缩 --- 提高效率:二分(未使用) **/
public static MultipartFile compressImage(MultipartFile file, long maxSize, double scale) throws IOException {
// 读取图片到BufferedImage
BufferedImage image = ImageIO.read(file.getInputStream());
// 初始压缩质量(范围0-1,1为最高质量)
double quality = 0.9;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String outputFormat = "jpg"; // 指定输出格式为jpg
// 统计循环次数
int count = 0;
byte[] compressedBytes;
double qualityStep = 0.1;
// 循环压缩直到图片大小满足要求
while (true) {
count ++;
// 使用Thumbnailator进行压缩
Thumbnails.of(image)
.scale(scale) // 保持原尺寸
.outputQuality(quality) // 设置输出质量
.outputFormat(outputFormat)
.toOutputStream(outputStream);
compressedBytes = outputStream.toByteArray();
long size = compressedBytes.length;
// 如果图片大小满足要求,则退出循环
if (size / 1024 <= maxSize) {
break;
}
// 否则降低压缩质量并清空输出流以进行下一次压缩
outputStream.reset();
// 更新压缩质量
quality -= qualityStep;
if (quality < qualityStep * 2) {
qualityStep /= 10;
}
if (count == 7) {
return ByteToMultipartFile(compressedBytes, System.currentTimeMillis()+".jpg", "image/jpeg");
}
}
return ByteToMultipartFile(compressedBytes, System.currentTimeMillis()+".jpg", "image/jpeg");
}
/**
* 图片压缩至指定大小以下
* @param file 文件流
* @param maxSize 最大kb
* @param minSize 最小kb
* @return
* @throws IOException
*/
public static MultipartFile compressImageToMaxSize(MultipartFile file, long maxSize, long minSize) throws IOException {
int n= 0;
double scale = 1.0;
double size = file.getSize() / 1024;
if (size > 1024) scale = 1.0 - size / 1024 < 0.3 ? 0.3 : 1.0 - size / 1024;
while (scale > 0.2) {
if (size < minSize) {
scale += 0.2;
}else if (size < maxSize) {
break;
}
file = compressImage(file, maxSize, scale);
size = file.getSize() / 1024;
scale -= 0.1;
}
if (size > maxSize) {
throw new IOException(file.getName()+file.getSize()+"图片过大!请压缩至50-200kb内");
}
if (size < minSize) {
throw new IOException(file.getName()+file.getSize()+"图片太小!请上传50-200kb的人脸照片");
}
return file;
}
}