欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot页面上传图片过大的后台解决办法-------------通过Thumbnails做图片压缩,图片格式转换------这一篇就够!

程序员文章站 2022-07-14 21:55:24
...

最近的未成年人保护在互联网也是一浪高过一浪,为了支持*的政策,对未成年人保护。我们的商城也做了个实名认证的功能。这个功能能够根据用户上传的身份证信息自动判定是否为未成年,进而做出相应的业务处理。

问题点1:在于我们使用的三方服务ocr接口限制文件传输为1M,也就是说你的图片过大,就会出现识别报错的问题。而现在的高像素手机,随便一拍就是几兆,必然要做图片压缩的处理。

问题点2:用户用的不同的手机,拍出来的照片,或者传输的照片的图片格式也是各式各样。但是三方服务接口就接受三种类型的图片。jpg,bmp,jpeg。没有办法。要么就是对别的类型在接口层控制住,提示用户格式不正确。要么处理图片的格式。
以上这就是本篇的业务场景,和要解决的问题点。


下面对上面的两个问题来做处理。 接口接受前端上传的照片:

代码分为三步

  1. 首先接收到图片文件后进行压缩,转换图片类型。也是本节要解决的问题!
  2. 对图片进行Base64转码。这个是三方服务的接口要求。
  3. 调用业务层进行后续操作。
    springboot页面上传图片过大的后台解决办法-------------通过Thumbnails做图片压缩,图片格式转换------这一篇就够!

1.首先是引入依赖:

        <!--图片压缩工具类thumbnailator-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>

2.然后就是代码部分。工具类

2.1 controller层的私有公共方法

    /**
     * [图片转换格式,压缩公共方法]
     *
     * @param multipartFile
     * @return
     * @throws IOException
     */
    private MultipartFile getCompressFile(MultipartFile multipartFile) throws IOException {
        List fileTypeList = new ArrayList();
        fileTypeList.add(FILE_TYPE_IMAGE_EXT_JPG.getId());
        fileTypeList.add(FILE_TYPE_IMAGE_EXT_BMP.getId());
        fileTypeList.add(FILE_TYPE_IMAGE_EXT_JPEG.getId());
        String filePath = FileUtil.getFileAbsolutePath("doc", "jpg");
        LOGGER.info("缓存文件的绝对路径:" + filePath);
        //图片压缩
        return ImageUtil.compressFile(multipartFile, filePath, fileTypeList);
    }

2.2 获取临时文件在服务器上的绝对路径的方法

import java.io.File;
import java.util.UUID;

/**
 * 文件操作工具类
 * @date 2019-11-09
 * @author zhanglifeng
 */
public class FileUtil {
    public static String getFileAbsolutePath(String filePath,String fileType){
        StringBuilder sb =new StringBuilder();
        String fileName = sb.append(UUID.randomUUID()).append(".").append(fileType).toString();
        sb.setLength(0);
        sb.append(FileUtil.class.getClassLoader().getResource("").getPath());
        sb.append(filePath).append(File.separator).append(fileName);
        String path = sb.toString().replaceAll("\\\\", "\\/");
        return path;
    }
}

2.3 压缩,转换图片类型的工具类


import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * 获取图片尺寸和截图 工具类
 *
 * @author zhanglifeng
 * @date 2019-11-08
 */
public class ImageUtil {
    private final static Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    /**
     * [压缩要上传的文件,并将文件类型转为指定的文件类型集合中的一个。]
     *
     * @param file         要上传的文件
     * @param absolutePath 临时文件的绝对路径
     * @param fileTypeList 文件转成的类型集合
     * @return
     */
    public static MultipartFile compressFile(MultipartFile file, String absolutePath, List<String> fileTypeList) throws IOException {
        //记录原MultipartFile,如果压缩异常就用原来的MultipartFile
        MultipartFile oldMultipartFile = file;
        FileInputStream fileInputStream = null;
        try {
            String fileName = file.getName();
            String originalFilename = file.getOriginalFilename();
            String contentType = file.getContentType();
            //获取要上传的文件后缀
            String fileExt = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            File tempFile = new File(absolutePath);
            if (fileTypeList.contains(fileExt)) {
                //如果文件类型符合,则只压缩就好了
                Thumbnails.of(file.getInputStream())
                        .scale(1f)
                        .outputQuality(0.2f)
                        .toFile(tempFile);
            } else {
                //如果文件类型不在指定的集合内。则要转格式,并压缩
                Thumbnails.of(file.getInputStream())
                        .scale(1f)
                        .outputFormat(fileTypeList.get(0))
                        .outputQuality(0.2f)
                        .toFile(tempFile);
                originalFilename = originalFilename.replace("." + fileExt, "." + fileTypeList.get(0));
            }
            fileInputStream = new FileInputStream(tempFile);
            file = new MockMultipartFile(fileName, originalFilename, contentType, fileInputStream);
            boolean success = tempFile.delete();
            logger.info("删除临时file success:{}", success);
        } catch (IOException e) {
            logger.error("压缩图片失败,把MultipartFile赋值为原来的值oldFile,exception:{}", e);
            file = oldMultipartFile;
        } finally {
            fileInputStream.close();
        }
        return file;
    }

}

然后可以本地通过postman调用测试接口,可以先注释掉删除临时文件的代码。可以看到压缩后的文件才几十到几百kb.
并且png格式的图片变成jpg格式的。目标达成!

如果感觉图片压缩的太过或者还要在压缩。可以调整这个值:outputQuality(0.2f)的大小。甚至可以一遍不行来两边。

参考博文:
1.文件上传MultipartFile实现图片压缩

2.java后台对上传的图片进行压缩

相关标签: 文件压缩