ImageCompressionUtils.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package com.ydtech.utils;
  2. import com.ydtech.exception.SystemException;
  3. import lombok.extern.slf4j.Slf4j;
  4. import net.coobird.thumbnailator.Thumbnails;
  5. import javax.imageio.ImageIO;
  6. import java.awt.*;
  7. import java.awt.image.BufferedImage;
  8. import java.io.*;
  9. import java.nio.file.Files;
  10. /**
  11. * @author wenks
  12. * @version 0.0.2
  13. * @description 文件压缩工具类
  14. * @date 2023/4/11 10:27
  15. */
  16. @Slf4j
  17. public class ImageCompressionUtils {
  18. private ImageCompressionUtils() {
  19. throw new IllegalStateException("Utility class");
  20. }
  21. private static final Integer ZERO = 0;
  22. private static final Integer ONE_ZERO_TWO_FOUR = 1024;
  23. private static final Integer NINE_ZERO_ZERO = 900;
  24. private static final Integer THREE_TWO_SEVEN_FIVE = 3275;
  25. private static final Integer TWO_ZERO_FOUR_SEVEN = 2047;
  26. private static final Double ZERO_EIGHT_FIVE = 0.85;
  27. private static final Double ZERO_SIX = 0.6;
  28. private static final Double ZERO_FOUR_FOUR = 0.44;
  29. private static final Double ZERO_FOUR = 0.4;
  30. /**
  31. * 压缩大小不变
  32. *
  33. * @param inputStream 输入流
  34. * @param suffix 文件后缀名
  35. * @param path 路劲
  36. * @return 字节
  37. */
  38. public static byte[] compressPic(InputStream inputStream, String suffix, String path) throws IOException {
  39. File temp = File.createTempFile("temp", suffix, new File(path));
  40. try (FileOutputStream os = new FileOutputStream(temp);) {
  41. BufferedImage image = ImageIO.read(inputStream);
  42. int width = image.getWidth();
  43. int height = image.getHeight();
  44. BufferedImage bfImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  45. bfImage.getGraphics().drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
  46. ImageIO.write(bfImage, suffix.replace(".", ""), os);
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. byte[] bytesByFile = getBytesByFile(temp);
  51. Files.delete(temp.getAbsoluteFile().toPath());
  52. return bytesByFile;
  53. }
  54. /**
  55. * 文件转字节
  56. *
  57. * @param file 文件
  58. * @return 字节
  59. */
  60. public static byte[] getBytesByFile(File file) {
  61. try (FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(1000)) {
  62. byte[] b = new byte[1000];
  63. int n;
  64. while ((n = fis.read(b)) != -1) {
  65. bos.write(b, 0, n);
  66. }
  67. return bos.toByteArray();
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. }
  71. return new byte[0];
  72. }
  73. /**
  74. * 根据指定大小压缩图片
  75. *
  76. * @param imageBytes 源图片字节数组
  77. * @param desFileSize 指定图片大小,单位kb
  78. * @return 压缩质量后的图片字节数组
  79. */
  80. public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
  81. if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) {
  82. return imageBytes;
  83. }
  84. long srcSize = imageBytes.length;
  85. double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR);
  86. try {
  87. while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) {
  88. ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
  89. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
  90. Thumbnails.of(inputStream)
  91. .scale(accuracy)
  92. .outputQuality(accuracy)
  93. .toOutputStream(outputStream);
  94. imageBytes = outputStream.toByteArray();
  95. }
  96. log.info("图片原大小={}kb | 压缩后大小={}kb",
  97. srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
  98. } catch (Exception e) {
  99. log.error("【图片压缩】msg=图片压缩失败!", e);
  100. throw new SystemException(e.toString());
  101. }
  102. return imageBytes;
  103. }
  104. /**
  105. * 自动调节精度(经验数值)
  106. *
  107. * @param size 源图片大小
  108. * @return 图片压缩质量比
  109. */
  110. private static double getAccuracy(long size) {
  111. double accuracy;
  112. if (size < NINE_ZERO_ZERO) {
  113. accuracy = ZERO_EIGHT_FIVE;
  114. } else if (size < TWO_ZERO_FOUR_SEVEN) {
  115. accuracy = ZERO_SIX;
  116. } else if (size < THREE_TWO_SEVEN_FIVE) {
  117. accuracy = ZERO_FOUR_FOUR;
  118. } else {
  119. accuracy = ZERO_FOUR;
  120. }
  121. return accuracy;
  122. }
  123. }