1. package com.atguigu.yygh.model.hosp;
  2. import net.coobird.thumbnailator.Thumbnails;
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. public class TuUtils {
  6. /**
  7. * 根据指定大小压缩图片
  8. *
  9. * @param imageBytes 源图片字节数组
  10. * @param desFileSize 指定图片大小,单位kb
  11. * @return 压缩质量后的图片字节数组
  12. */
  13. public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
  14. if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
  15. return null;
  16. }
  17. long srcSize = imageBytes.length;
  18. double accuracy = getAccuracy(srcSize / 1024);
  19. try {
  20. while (imageBytes.length > desFileSize * 1024) {
  21. ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
  22. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
  23. Thumbnails.of(inputStream)
  24. .scale(accuracy)
  25. .outputQuality(accuracy)
  26. .toOutputStream(outputStream);
  27. imageBytes = outputStream.toByteArray();
  28. }
  29. //log.info("【图片压缩】| 图片原大小={" + srcSize / 1024 + "}kb | 压缩后大小={" + imageBytes.length / 1024 + "}kb | ");
  30. } catch (Exception e) {
  31. //log.error("【图片压缩】msg=图片压缩失败!" + e);
  32. // DefaultMonitorImpl.pushException("【图片压缩】msg=图片压缩失败!" + e);
  33. }
  34. return imageBytes;
  35. }
  36. /**
  37. * 自动调节精度(经验数值)
  38. *
  39. * @param size 源图片大小
  40. * @return 图片压缩质量比
  41. */
  42. private static double getAccuracy(long size) {
  43. double accuracy;
  44. if (size < 900) {
  45. accuracy = 0.85;
  46. } else if (size < 2047) {
  47. accuracy = 0.6;
  48. } else if (size < 3275) {
  49. accuracy = 0.44;
  50. } else {
  51. accuracy = 0.4;
  52. }
  53. return accuracy;
  54. }
  55. /**
  56. *
  57. * 图片字节数组转MultipartFile
  58. * InputStream inputStream2 = new ByteArrayInputStream(imageBytes);
  59. * MultipartFile file2 = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream2);
  60. *
  61. */
  62. }

依赖jar包

net.coobird
thumbnailator
0.4.8

————————————————————————————————————-以下为网络资料

我们在java开发时,使用Thumbnails工具类能帮助我们对图片进行很好的处理,Thumbnails对图片的操作进行了很好的封装,往往很复杂的步骤能用一行代码就完成。
Thumbnails支持:
·指定大小进行缩放
·按照比例进行缩放
·不按照比例,指定大小进行缩放
·旋转
·水印
·裁剪
·转化图像格式
·输出到OutputStream
·输出到BufferedImage
使用步骤

  1. 导入架包


net.coobird
thumbnailator
0.4.8

2.具体使用方法

  1. /**
  2. * 指定大小进行缩放
  3. *
  4. * @throws IOException
  5. */
  6. private void test1() throws IOException {
  7. /*
  8. * size(width,height) 若图片横比200小,高比300小,不变
  9. * 若图片横比200小,高比300大,高缩小到300,图片比例不变 若图片横比200大,高比300小,横缩小到200,图片比例不变
  10. * 若图片横比200大,高比300大,图片按比例缩小,横为200或高为300
  11. */
  12. Thumbnails.of("images/test.jpg").size(200, 300).toFile("C:/image_200x300.jpg");
  13. Thumbnails.of("images/test.jpg").size(2560, 2048).toFile("C:/image_2560x2048.jpg");
  14. }
  15. /**
  16. * 按照比例进行缩放
  17. *
  18. * @throws IOException
  19. */
  20. private void test2() throws IOException {
  21. /**
  22. * scale(比例)
  23. */
  24. Thumbnails.of("images/test.jpg").scale(0.25f).toFile("C:/image_25%.jpg");
  25. Thumbnails.of("images/test.jpg").scale(1.10f).toFile("C:/image_110%.jpg");
  26. }
  27. /**
  28. * 不按照比例,指定大小进行缩放
  29. *
  30. * @throws IOException
  31. */
  32. private void test3() throws IOException {
  33. /**
  34. * keepAspectRatio(false) 默认是按照比例缩放的
  35. */
  36. Thumbnails.of("images/test.jpg").size(120, 120).keepAspectRatio(false).toFile("C:/image_120x120.jpg");
  37. }
  38. /**
  39. * 旋转
  40. *
  41. * @throws IOException
  42. */
  43. private void test4() throws IOException {
  44. /**
  45. * rotate(角度),正数:顺时针 负数:逆时针
  46. */
  47. Thumbnails.of("images/test.jpg").size(1280, 1024).rotate(90).toFile("C:/image+90.jpg");
  48. Thumbnails.of("images/test.jpg").size(1280, 1024).rotate(-90).toFile("C:/iamge-90.jpg");
  49. }
  50. /**
  51. * 水印
  52. *
  53. * @throws IOException
  54. */
  55. private void test5() throws IOException {
  56. /**
  57. * watermark(位置,水印图,透明度)
  58. */
  59. Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), 0.5f)
  60. .outputQuality(0.8f).toFile("C:/image_watermark_bottom_right.jpg");
  61. Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.CENTER, ImageIO.read(new File("images/watermark.png")), 0.5f)
  62. .outputQuality(0.8f).toFile("C:/image_watermark_center.jpg");
  63. }
  64. /**
  65. * 裁剪
  66. *
  67. * @throws IOException
  68. */
  69. private void test6() throws IOException {
  70. /**
  71. * 图片中心400*400的区域
  72. */
  73. Thumbnails.of("images/test.jpg").sourceRegion(Positions.CENTER, 400, 400).size(200, 200).keepAspectRatio(false)
  74. .toFile("C:/image_region_center.jpg");
  75. /**
  76. * 图片右下400*400的区域
  77. */
  78. Thumbnails.of("images/test.jpg").sourceRegion(Positions.BOTTOM_RIGHT, 400, 400).size(200, 200).keepAspectRatio(false)
  79. .toFile("C:/image_region_bootom_right.jpg");
  80. /**
  81. * 指定坐标
  82. */
  83. Thumbnails.of("images/test.jpg").sourceRegion(600, 500, 400, 400).size(200, 200).keepAspectRatio(false).toFile("C:/image_region_coord.jpg");
  84. }
  85. /**
  86. * 转化图像格式
  87. *
  88. * @throws IOException
  89. */
  90. private void test7() throws IOException {
  91. /**
  92. * outputFormat(图像格式)
  93. */
  94. Thumbnails.of("images/test.jpg").size(1280, 1024).outputFormat("png").toFile("C:/image_1280x1024.png");
  95. Thumbnails.of("images/test.jpg").size(1280, 1024).outputFormat("gif").toFile("C:/image_1280x1024.gif");
  96. }
  97. /**
  98. * 输出到OutputStream
  99. *
  100. * @throws IOException
  101. */
  102. private void test8() throws IOException {
  103. /**
  104. * toOutputStream(流对象)
  105. */
  106. OutputStream os = new FileOutputStream("C:/image_1280x1024_OutputStream.png");
  107. Thumbnails.of("images/test.jpg").size(1280, 1024).toOutputStream(os);
  108. }
  109. /**
  110. * 输出到BufferedImage
  111. *
  112. * @throws IOException
  113. */
  114. private void test9() throws IOException {
  115. /**
  116. * asBufferedImage() 返回BufferedImage
  117. */
  118. BufferedImage thumbnail = Thumbnails.of("images/test.jpg").size(1280, 1024).asBufferedImage();
  119. ImageIO.write(thumbnail, "jpg", new File("C:/image_1280x1024_BufferedImage.jpg"));
  120. }

压缩图片至指定大小

一开始没有思路在网上搜,发现google有个插件叫Thumbnails,然后看到了这篇文章:
https://blog.csdn.net/u010355502/article/details/77197616
思路很简单,按一定的比例压缩图片,如果压缩完大小达不到要求,就把压缩后的结果继续压缩,直到符合要求为止
本文可以说是对原文作者代码的改进,去除了一些多余的IO过程,把递归改成了循环,并且把文件操作改为了流和字节数组的操作(也是更符合公司的业务代码一些)
在此感谢原文作者

  1. import net.coobird.thumbnailator.Thumbnails;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import java.io.ByteArrayInputStream;
  5. import java.io.ByteArrayOutputStream;
  6. /**
  7. * 图片压缩Utils
  8. *
  9. * @author worstEzreal
  10. * @version V1.1.0
  11. * @date 2018/3/12
  12. */
  13. public class PicUtils {
  14. private static Logger logger = LoggerFactory.getLogger(PicUtils.class);
  15. // public static void main(String[] args) throws IOException {
  16. // byte[] bytes = FileUtils.readFileToByteArray(new File("D:\\1.jpg"));
  17. // long l = System.currentTimeMillis();
  18. // bytes = PicUtils.compressPicForScale(bytes, 300, "x");// 图片小于300kb
  19. // System.out.println(System.currentTimeMillis() - l);
  20. // FileUtils.writeByteArrayToFile(new File("D:\\dd1.jpg"), bytes);
  21. // }
  22. /**
  23. * 根据指定大小压缩图片
  24. *
  25. * @param imageBytes 源图片字节数组
  26. * @param desFileSize 指定图片大小,单位kb
  27. * @param imageId 影像编号
  28. * @return 压缩质量后的图片字节数组
  29. */
  30. public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId) {
  31. if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
  32. return imageBytes;
  33. }
  34. long srcSize = imageBytes.length;
  35. double accuracy = getAccuracy(srcSize / 1024);
  36. try {
  37. while (imageBytes.length > desFileSize * 1024) {
  38. ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
  39. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
  40. Thumbnails.of(inputStream)
  41. .scale(accuracy)
  42. .outputQuality(accuracy)
  43. .toOutputStream(outputStream);
  44. imageBytes = outputStream.toByteArray();
  45. }
  46. logger.info("【图片压缩】imageId={} | 图片原大小={}kb | 压缩后大小={}kb",
  47. imageId, srcSize / 1024, imageBytes.length / 1024);
  48. } catch (Exception e) {
  49. logger.error("【图片压缩】msg=图片压缩失败!", e);
  50. }
  51. return imageBytes;
  52. }
  53. /**
  54. * 自动调节精度(经验数值)
  55. *
  56. * @param size 源图片大小
  57. * @return 图片压缩质量比
  58. */
  59. private static double getAccuracy(long size) {
  60. double accuracy;
  61. if (size < 900) {
  62. accuracy = 0.85;
  63. } else if (size < 2047) {
  64. accuracy = 0.6;
  65. } else if (size < 3275) {
  66. accuracy = 0.44;
  67. } else {
  68. accuracy = 0.4;
  69. }
  70. return accuracy;
  71. }
  72. }