基于SpringBoot实现图片上传并生成缩略图功能

 更新时间:2025年08月17日 11:30:38   作者:火皇405  
在实际开发中,上传图片并生成缩略图是一项常见需求,例如在电商平台、社交应用等场景中,缩略图可以有效提高页面加载速度,优化用户体验,本文将介绍如何在 Spring Boot 项目中实现上传图片并生成缩略图的功能,需要的朋友可以参考下

在实际开发中,上传图片并生成缩略图是一项常见需求,例如在电商平台、社交应用等场景中,缩略图可以有效提高页面加载速度,优化用户体验。本文将介绍如何在 Spring Boot 项目中实现上传图片并生成缩略图的功能。

1. 依赖配置

pom.xml 文件中添加以下依赖:

<!-- Spring Boot Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<!-- 文件上传 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
 
<!-- 图片处理依赖 -->
<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-core</artifactId>
    <version>3.8.1</version>
</dependency>
 
<!-- Apache Commons IO -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

2. 核心代码实现

以下方法将实现图片上传并生成缩略图的功能:

import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
 
public String uploadPictureThumbnail(String bucketName, MultipartFile multipartFile, Long assocId, String originalStorageName, Integer scale, Integer width, Integer height) {
    String directoryPath = "";
    if (OsUtils.isLinux()) {
        directoryPath = "/tempdir";
    } else if (OsUtils.isWindows()) {
        directoryPath = "C:/tempdir";
    }
 
    File directory = new File(directoryPath);
    if (!directory.exists()) {
        directory.mkdir();
    }
 
    String originalName = multipartFile.getOriginalFilename();
    String suffixName = getSuffixName(originalName, ".", 0);
    String suffix = getSuffixName(originalName, ".", 1);
    String storageName = UUID.randomUUID().toString() + suffixName;
    String storageFileName = null;
 
    List<String> thumbnailSuffixName = Arrays.asList(".png", ".jpg", ".jpeg", ".gif");
    if (thumbnailSuffixName.contains(suffixName.toLowerCase())) {
        try {
            // 保存原始图片
            String originalImagePath = directoryPath + "/" + storageName;
            Path filePath = Paths.get(originalImagePath);
            Files.write(filePath, multipartFile.getBytes());
 
            // 读取原始图片并生成缩略图
            BufferedImage originalImage = ImageIO.read(new File(originalImagePath));
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();
 
            // 计算缩略图尺寸
            int[] data = computeSize(originalWidth, originalHeight, scale, width, height);
            int thumbnailWidth = data[0];
            int thumbnailHeight = data[1];
 
            Image scaledImage = originalImage.getScaledInstance(thumbnailWidth, thumbnailHeight, Image.SCALE_SMOOTH);
            BufferedImage thumbnailImage = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = thumbnailImage.createGraphics();
            g2d.drawImage(scaledImage, 0, 0, null);
            g2d.dispose();
 
            // 保存缩略图
            String thumbnailPath = directoryPath + "/" + UUID.randomUUID().toString() + suffixName;
            File thumbnailFile = new File(thumbnailPath);
            ImageIO.write(thumbnailImage, suffix.replace(".", ""), thumbnailFile);
 
            // 上传缩略图(这里用自定义 uploadFile 方法上传到对象存储)
            try (FileInputStream in = new FileInputStream(thumbnailFile)) {
                String name = getSuffixName(originalStorageName, "/", 1);
                storageFileName = uploadFile(bucketName, in, multipartFile.getContentType(), assocId, thumbnailFile.length(), name, "thumbnail");
            }
 
            // 清理临时文件
            new File(originalImagePath).delete();
            thumbnailFile.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return storageFileName;
}

3. 计算缩略图尺寸方法

根据原始尺寸、比例、指定宽高生成合适的缩略图尺寸:

private int[] computeSize(int originalWidth, int originalHeight, Integer scale, Integer width, Integer height) {
    if (scale != null && scale > 0) {
        return new int[]{originalWidth * scale / 100, originalHeight * scale / 100};
    } else if (width != null && height != null) {
        return new int[]{width, height};
    } else {
        // 默认缩小为原始尺寸的 50%
        return new int[]{originalWidth / 2, originalHeight / 2};
    }
}

4. 工具方法示例

用于提取文件后缀名:

5. 注意事项

  1. 操作系统临时目录:根据不同操作系统,创建不同的临时文件夹路径。
  2. 文件清理:上传完成后及时删除临时文件,避免占用过多磁盘空间。
  3. 缩略图格式支持:目前支持 PNG、JPG、JPEG、GIF 格式。
  4. 上传逻辑uploadFile 方法需根据具体的存储服务(例如 MinIO、OSS、七牛云等)自定义实现。

6. 总结

通过以上步骤,我们成功实现了图片上传并生成缩略图的功能。此功能不仅能有效减少图片加载时间,还能节省存储空间,提升系统性能。

到此这篇关于基于SpringBoot实现图片上传并生成缩略图功能的文章就介绍到这了,更多相关SpringBoot图片上传并生成缩略图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis传递多个参数方式

    MyBatis传递多个参数方式

    这篇文章主要介绍了MyBatis传递多个参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • SpringMvc+Mybatis+Pagehelper分页详解

    SpringMvc+Mybatis+Pagehelper分页详解

    这篇文章主要介绍了SpringMvc+Mybatis+Pagehelper分页详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下的相关资料
    2017-01-01
  • Java Object类equals方法

    Java Object类equals方法

    这篇文章主要介绍了Java Object类equals方法,Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入,下文更多相关介绍,需要的小伙伴可以参考一下
    2022-04-04
  • springboot整合mybatis plus与druid详情

    springboot整合mybatis plus与druid详情

    这篇文章主要介绍了springboot整合mybatis plus与druid详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的下伙伴可以参考一下
    2022-09-09
  • SpringBoot使用前缀树过滤敏感词的方法实例

    SpringBoot使用前缀树过滤敏感词的方法实例

    Trie也叫做字典树、前缀树(Prefix Tree)、单词查找树,特点:查找效率高,消耗内存大,这篇文章主要给大家介绍了关于SpringBoot使用前缀树过滤敏感词的相关资料,需要的朋友可以参考下
    2022-01-01
  • MyBatis如何通过xml方式实现SaveOrUpdate

    MyBatis如何通过xml方式实现SaveOrUpdate

    这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-06-06
  • Java关键字super超详细解释

    Java关键字super超详细解释

    在Java中super是一个关键字,用于访问父类中的属性、方法或构造函数,这篇文章主要给大家介绍了关于Java关键字super超详细解释的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • java数据类型与变量的安全性介绍

    java数据类型与变量的安全性介绍

    这篇文章主要介绍了java数据类型与变量的安全性介绍,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • 在idea中创建SpringBoot项目

    在idea中创建SpringBoot项目

    这篇文章主要介绍了在idea中创建SpringBoot项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • java与php的区别浅析

    java与php的区别浅析

    在本篇文章里小编给大家整理了关于java与php的区别以及相关知识点,有兴趣的朋友们学习下。
    2019-03-03

最新评论