拿图片不得大于1M为例,代码如下:
@PostMapping("upload")
public void upload(@RequestParam("images") List<MultipartFile> files) throws IOException {
// 处理files
for (int i = 0; i < files.size(); i++) {
MultipartFile file = files.get(i);
// 保存文件到服务器或处理文件
System.out.println(file.getOriginalFilename());
String base64 = Base64ToCompressedImage.processImage(file);
System.out.println(base64);
}
...
...
}
// 图片不得大于1MB
private static final int MAX_SIZE_BYTES = 1024 * 1024;
// 初始压缩质量设为0.75
private static final float quality = 0.75f;
public static String processImage(MultipartFile file) throws IOException {
// 读取MultipartFile到BufferedImage
BufferedImage image = ImageIO.read(file.getInputStream());
if (image == null) {
throw new IOException("Invalid image format");
}
// 检查原始图片大小
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos); // 假设我们总是转换为JPG来压缩(如果需要)
byte[] originalBytes = baos.toByteArray();
if (originalBytes.length <= MAX_SIZE_BYTES) {
// 图片大小已经符合要求,直接转换为Base64
return Base64.getEncoder().encodeToString(originalBytes);
}
// 图片需要压缩
return compressImageAndConvertToBase64(image, quality);
}
private static String compressImageAndConvertToBase64(BufferedImage image, float initialQuality) throws IOException {
// JPEG图片格式
String formatName = "JPEG";
// 获取能写入JPEG格式的ImageWriter
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
if (!writers.hasNext()) {
throw new IllegalStateException("No writers are found");
}
ImageWriter writer = writers.next();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
float quality = initialQuality;
while (true) {
param.setCompressionQuality(quality);
IIOImage iioImage = new IIOImage(image, null, null);
writer.write(null, iioImage, param);
if (baos.size() <= MAX_SIZE_BYTES) {
return Base64.getEncoder().encodeToString(baos.toByteArray());
} else if (quality > 0.1f) {
quality -= 0.1f;
baos.reset(); // 重置ByteArrayOutputStream
} else {
throw new IOException("Image could not be compressed to under 1MB even at minimum quality.");
}
}
} else {
throw new IllegalStateException("Compression not supported.");
}
} finally {
writer.dispose();
}
}
MAX_SIZE_BYTES:图片最大大小
quality :图片初始压缩质量
以上就是图片压缩的过程,亲测好用!