CompressUtil.java 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package com.qs.mp.common.image;
  2. import com.qs.mp.common.utils.LogUtil;
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. import net.coobird.thumbnailator.Thumbnails;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. /**
  9. * 压缩工具类
  10. *
  11. * @author zhongcp
  12. * @Date 2022/4/16
  13. */
  14. public class CompressUtil {
  15. protected static final Logger logger = LoggerFactory.getLogger(CompressUtil.class);
  16. private static final Integer ZERO = 0;
  17. private static final Integer ONE_ZERO_TWO_FOUR = 1024;
  18. private static final Integer NINE_ZERO_ZERO = 400;
  19. private static final Integer THREE_TWO_SEVEN_FIVE = 2047;
  20. private static final Integer TWO_ZERO_FOUR_SEVEN = 900;
  21. private static final Double ZERO_EIGHT_FIVE = 0.85;
  22. private static final Double ZERO_SIX = 0.6;
  23. private static final Double ZERO_FOUR_FOUR = 0.44;
  24. private static final Double ZERO_FOUR = 0.4;
  25. /**
  26. * 根据指定大小压缩图片
  27. *
  28. * @param imageBytes 源图片字节数组
  29. * @param desFileSize 指定图片大小,单位kb
  30. * @return 压缩质量后的图片字节数组
  31. */
  32. public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
  33. if (imageBytes == null || imageBytes.length <= ZERO
  34. || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) {
  35. return imageBytes;
  36. }
  37. long srcSize = imageBytes.length;
  38. double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR);
  39. try {
  40. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
  41. while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) {
  42. ByteArrayInputStream inputStream = null;
  43. try {
  44. inputStream = new ByteArrayInputStream(imageBytes);
  45. Thumbnails.of(inputStream)
  46. .scale(accuracy)
  47. .outputQuality(accuracy)
  48. .toOutputStream(outputStream);
  49. imageBytes = outputStream.toByteArray();
  50. } finally {
  51. if (null != inputStream) {
  52. inputStream.close();
  53. }
  54. }
  55. }
  56. LogUtil.info(logger, "图片原大小={}kb | 压缩后大小={}kb",
  57. srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
  58. } catch (Exception e) {
  59. LogUtil.error(logger, "【图片压缩】msg=图片压缩失败!", e);
  60. }
  61. return imageBytes;
  62. }
  63. /**
  64. * 自动调节精度(经验数值)
  65. *
  66. * @param size 源图片大小
  67. * @return 图片压缩质量比
  68. */
  69. public static double getAccuracy(long size) {
  70. double accuracy;
  71. if (size < NINE_ZERO_ZERO) {
  72. accuracy = ZERO_EIGHT_FIVE;
  73. } else if (size < TWO_ZERO_FOUR_SEVEN) {
  74. accuracy = ZERO_SIX;
  75. } else if (size < THREE_TWO_SEVEN_FIVE) {
  76. accuracy = ZERO_FOUR_FOUR;
  77. } else {
  78. accuracy = ZERO_FOUR;
  79. }
  80. return accuracy;
  81. }
  82. }