|
@@ -42,7 +42,7 @@ import java.util.zip.ZipOutputStream;
|
|
|
import com.drew.metadata.MetadataException;
|
|
|
import org.springframework.util.ResourceUtils;
|
|
|
import org.springframework.web.util.UriUtils;
|
|
|
-
|
|
|
+import net.coobird.thumbnailator.Thumbnails;
|
|
|
/**
|
|
|
* 通用工具类
|
|
|
*
|
|
@@ -840,6 +840,82 @@ public class CommonUtil {
|
|
|
return baos.toByteArray();
|
|
|
}
|
|
|
|
|
|
+ public static byte[] compressImage3(String url) throws IOException, ImageProcessingException, MetadataException {
|
|
|
+ try(InputStream file = CommonUtil.getOSSInputStream(url)) {
|
|
|
+ byte[] imageData = InputStreamToBytes(file);
|
|
|
+ return compressImage3(imageData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte[] compressImage3(byte[] imageData) throws ImageProcessingException, IOException, MetadataException {
|
|
|
+ // 读取原始图像(处理旋转问题)
|
|
|
+ int orientation = 1;
|
|
|
+ Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
|
|
|
+ if (metadata.containsDirectoryOfType(ExifIFD0Directory.class)) {
|
|
|
+ ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
|
|
|
+ if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
|
|
|
+ // 获取 Orientation 标签的值
|
|
|
+ orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 缩放图像
|
|
|
+ String formatName = "JPEG";
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ long sizeLimit = 1024*1024*5; //5M 1920 ×1080
|
|
|
+ int width = 1080;
|
|
|
+ int height = 1920;
|
|
|
+ // 需要旋转图片
|
|
|
+ // 1 无需纠正 2 水平翻转(镜像)3 垂直翻转(旋转180°) 4 水平翻转+垂直翻转 5 水平翻转+旋转90°
|
|
|
+ // 6 旋转90° 7 水平翻转+旋转270° 8 +旋转270°
|
|
|
+ float quality = 0.99f; // 初始化压缩质量
|
|
|
+ int retries = 10; // 最多尝试 10 次
|
|
|
+ double rotate = 0;
|
|
|
+ if (orientation > 1) {
|
|
|
+ if (orientation == 3) {
|
|
|
+ rotate = 180;
|
|
|
+ } else if (orientation == 6) {
|
|
|
+ rotate = 90;
|
|
|
+ } else if (orientation == 8) {
|
|
|
+ rotate = 270;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rotateAndScaleImageByThumbnails(new ByteArrayInputStream(imageData),baos, rotate, formatName, quality, width, height, true);
|
|
|
+ if (baos.size() <= sizeLimit) {
|
|
|
+ // 图片大小已经小于等于目标大小,直接返回原始数据
|
|
|
+ return baos.toByteArray();
|
|
|
+ }
|
|
|
+ ByteArrayInputStream bais;
|
|
|
+ while (baos.size() > sizeLimit && retries > 0) {
|
|
|
+ // 压缩图像并重新计算压缩质量
|
|
|
+ byte[] data = baos.toByteArray();
|
|
|
+ bais = new ByteArrayInputStream(data);
|
|
|
+ rotateAndScaleImageByThumbnails(bais,baos, 0, formatName, quality, width, height, true);
|
|
|
+ float ratio = sizeLimit * 1.0f / baos.size();
|
|
|
+ quality *= Math.sqrt(ratio);
|
|
|
+ retries--;
|
|
|
+ }
|
|
|
+ return baos.toByteArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param is URL InputStream File BufferedImage path
|
|
|
+ * @param os 输出流
|
|
|
+ * @param rotate 旋转角度(正数顺时针,负数逆时针)
|
|
|
+ * @param format 输出格式,jpg,jpeg,png等
|
|
|
+ * @param quality 输出质量(0.0-1.0)
|
|
|
+ * @param width 宽
|
|
|
+ * @param height 高
|
|
|
+ * @param keepAspectRatio 是否保持原比例
|
|
|
+ */
|
|
|
+ public static void rotateAndScaleImageByThumbnails(InputStream is, OutputStream os, double rotate, String format, double quality, int width, int height, boolean keepAspectRatio) throws IOException {
|
|
|
+ Thumbnails.of(is)
|
|
|
+ .size(width, height)
|
|
|
+ .keepAspectRatio(keepAspectRatio)
|
|
|
+ .rotate(rotate)
|
|
|
+ .outputFormat(format)
|
|
|
+ .outputQuality(quality)
|
|
|
+ .toOutputStream(os);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 根据起止日期获取工作日
|