写给大忙人看的 - Java中图片压缩上传至MinIO服务器(四)

客官°小女子只卖身不卖艺 2022-12-02 13:56 375阅读 0赞

之前文章已经介绍了 MinIO 的环境搭建,已经对文件的上传下载方法,本篇文章一起与大家来学习图片压缩上传的方法

1、背景

最近客户总抱怨 APP 中图片显示较慢, 升级服务器带宽又没有多的预算。查看原因,是因为现在大家都是用的智能手机拍照,拍出来的照片小则 2-3 M,大则十几 M,所以导致图片显示较慢。思考再三,决定将图片进行压缩再上传图片服务器来解决图片显示慢的问题

2、开发前戏

1、引入 maven 依赖

  1. <!-- 图片压缩 -->
  2. <dependency>
  3. <groupId>net.coobird</groupId>
  4. <artifactId>thumbnailator</artifactId>
  5. <version>0.4.8</version>
  6. </dependency>

本次我们选择了使用 thumbnailator 来作为压缩的工具

2、thumbnailator 简介

  • Thumbnailator 是一个用来生成图像缩略图的 Java 类库,通过很简单的代码即可生成图片缩略图,也可直接对一整个目录的图片生成缩略图
  • 支持图片缩放,区域裁剪,水印,旋转,保持比例

3、压缩前戏

  • 判断是否是图片方法

    /* 判断文件是否为图片 */
    public boolean isPicture(String imgName) {

    1. boolean flag = false;
    2. if (StringUtils.isBlank(imgName)) {
    3. return false;
    4. }
    5. String[] arr = { "bmp", "dib", "gif", "jfif", "jpe", "jpeg", "jpg", "png", "tif", "tiff", "ico"};
    6. for (String item : arr) {
    7. if (item.equals(imgName)) {
    8. flag = true;
    9. break;
    10. }
    11. }
    12. return flag;

    }

3、压缩上传

  1. /** * 上传文件 * * @param file 文件 * @return */
  2. public JSONObject uploadFile(MultipartFile file) throws Exception {
  3. JSONObject res = new JSONObject();
  4. res.put("code", 500);
  5. // 判断上传文件是否为空
  6. if (null == file || 0 == file.getSize()) {
  7. res.put("msg", "上传文件不能为空");
  8. return res;
  9. }
  10. // 判断存储桶是否存在
  11. if (!client.bucketExists("test")) {
  12. client.makeBucket("test");
  13. }
  14. // 拿到文件后缀名,例如:png
  15. String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
  16. // UUID 作为文件名
  17. String uuid = String.valueOf(UUID.randomUUID());
  18. // 新的文件名
  19. String fileName = DateUtils.getYyyymmdd() + "/" + uuid + "." + suffix;
  20. /** * 判断是否是图片 * 判断是否超过了 100K */
  21. if (isPicture(suffix) && (1024 * 1024 * 0.1) <= file.getSize()) {
  22. // 在项目根目录下的 upload 目录中生成临时文件
  23. File newFile = new File(ClassUtils.getDefaultClassLoader().getResource("upload").getPath() + uuid + "." + suffix);
  24. // 小于 1M 的
  25. if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) {
  26. Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.3f).toFile(newFile);
  27. }
  28. // 1 - 2M 的
  29. else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) {
  30. Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile);
  31. }
  32. // 2M 以上的
  33. else if ((1024 * 1024 * 2) < file.getSize()) {
  34. Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile);
  35. }
  36. // 获取输入流
  37. FileInputStream input = new FileInputStream(newFile);
  38. // 转为 MultipartFile
  39. MultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), "text/plain", input);
  40. // 开始上传
  41. client.putObject("test", fileName, multipartFile.getInputStream(), file.getContentType());
  42. // 删除临时文件
  43. newFile.delete();
  44. // 返回状态以及图片路径
  45. res.put("code", 200);
  46. res.put("msg", "上传成功");
  47. res.put("url", minioProp.getEndpoint() + "/" + "test" + "/" + fileName);
  48. }
  49. // 不需要压缩,直接上传
  50. else {
  51. // 开始上传
  52. client.putObject("test", fileName, file.getInputStream(), file.getContentType());
  53. // 返回状态以及图片路径
  54. res.put("code", 200);
  55. res.put("msg", "上传成功");
  56. res.put("url", minioProp.getEndpoint() + "/" + "test" + "/" + fileName);
  57. }
  58. return res;
  59. }
  • 这里我们判断了当文件为图片的时候,且当它大小超过了 (1024 * 1024 * 0.1),约为 100K 的时候,才进行压缩
  • 我们首先在根目录下的 upload 目录中创建了一个临时文件 newFile
  • Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.3f).toFile(newFile);将压缩后的文件输出到临时文件中
  • 然后将 FileInputStream 转为 MultipartFile 上传
  • 最后删除临时文件 newFile.delete();
  • 完成图片压缩上传

4、测试

  • 原图 706K

原图

  • 压缩后 120K

压缩后

5、总结

  • 综合以上代码,可以看出 Thumbnails 对图片的处理是很方便的,且代码量也非常少
  • 通过测试,可以看出压缩后的图片质量也很高
  • thumbnailator 对图片的处理支持全面,缩放,裁剪等

如您在阅读中发现不足,欢迎留言!!!

发表评论

表情:
评论列表 (有 0 条评论,375人围观)

还没有评论,来说两句吧...

相关阅读