|
|
@@ -0,0 +1,77 @@
|
|
|
+package cn.reghao.tnb.file.app.util;
|
|
|
+
|
|
|
+import net.coobird.thumbnailator.Thumbnails;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.imageio.IIOImage;
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import javax.imageio.ImageWriteParam;
|
|
|
+import javax.imageio.ImageWriter;
|
|
|
+import javax.imageio.stream.ImageOutputStream;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2026-06-17 15:58:42
|
|
|
+ */
|
|
|
+public class ImageUtil {
|
|
|
+ /**
|
|
|
+ * 将上传的图片统一转换为 WebP 格式并压缩
|
|
|
+ * @param file 上传的原始图片
|
|
|
+ * @param quality 压缩质量 (0.0f - 1.0f),推荐 0.75f
|
|
|
+ */
|
|
|
+ public static byte[] convertToWebp(File file, float quality) throws IOException {
|
|
|
+ // 1. 读取原图片
|
|
|
+ BufferedImage image = ImageIO.read(file);
|
|
|
+
|
|
|
+ // 2. 获取 WebP 的 ImageWriter
|
|
|
+ ImageWriter writer = ImageIO.getImageWritersByFormatName("webp").next();
|
|
|
+
|
|
|
+ // 3. 设置压缩参数
|
|
|
+ ImageWriteParam writeParam = writer.getDefaultWriteParam();
|
|
|
+ writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
|
|
+ // 这里指定有损压缩类型(如果想无损可以设为 Lossless)
|
|
|
+ writeParam.setCompressionType(writeParam.getCompressionTypes()[Choice.LOSSY.ordinal()]);
|
|
|
+ writeParam.setCompressionQuality(quality); // 比如 0.75f
|
|
|
+
|
|
|
+ // 4. 利用配置输出流
|
|
|
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
|
|
|
+ writer.setOutput(ios);
|
|
|
+
|
|
|
+ // 5. 写入数据
|
|
|
+ writer.write(null, new IIOImage(image, null, null), writeParam);
|
|
|
+ writer.dispose();
|
|
|
+ return baos.toByteArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum Choice {
|
|
|
+ LOSSY, LOSSLESS
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 自动压缩图片
|
|
|
+ * @param in 上传的原始图片文件流
|
|
|
+ * @param quality 压缩质量 (0.0f - 1.0f),推荐 0.6f - 0.8f
|
|
|
+ * @return 压缩后的图片字节数组
|
|
|
+ */
|
|
|
+ public static byte[] compressImage(InputStream in, float quality) throws IOException {
|
|
|
+ // 1. 获取上传文件的输入流
|
|
|
+ try (InputStream inputStream = in;
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
|
|
+
|
|
|
+ // 2. 使用 Thumbnailator 进行压缩
|
|
|
+ Thumbnails.of(inputStream)
|
|
|
+ .scale(1.0f) // 保持原图尺寸不变(如需改变尺寸,可传入如 0.5f 等)
|
|
|
+ .outputQuality(quality) // 设置压缩质量
|
|
|
+ .outputFormat("jpg") // 强制转换为 jpg 格式(jpg 的压缩率最高,如果是 png 建议转 jpg 减小体积)
|
|
|
+ .toOutputStream(outputStream);
|
|
|
+
|
|
|
+ // 3. 返回压缩后的字节数组
|
|
|
+ return outputStream.toByteArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|