springboot頁面上傳圖片過大的後臺解決辦法-------------通過Thumbnails做圖片壓縮,圖片格式轉換------這一篇就夠!

最近的未成年人保護在互聯網也是一浪高過一浪,爲了支持政府的政策,對未成年人保護。我們的商城也做了個實名認證的功能。這個功能能夠根據用戶上傳的身份證信息自動判定是否爲未成年,進而做出相應的業務處理。

問題點1:在於我們使用的三方服務ocr接口限制文件傳輸爲1M,也就是說你的圖片過大,就會出現識別報錯的問題。而現在的高像素手機,隨便一拍就是幾兆,必然要做圖片壓縮的處理。

問題點2:用戶用的不同的手機,拍出來的照片,或者傳輸的照片的圖片格式也是各式各樣。但是三方服務接口就接受三種類型的圖片。jpg,bmp,jpeg。沒有辦法。要麼就是對別的類型在接口層控制住,提示用戶格式不正確。要麼處理圖片的格式。
以上這就是本篇的業務場景,和要解決的問題點。


下面對上面的兩個問題來做處理。 接口接受前端上傳的照片:

代碼分爲三步

  1. 首先接收到圖片文件後進行壓縮,轉換圖片類型。也是本節要解決的問題!
  2. 對圖片進行Base64轉碼。這個是三方服務的接口要求。
  3. 調用業務層進行後續操作。
    在這裏插入圖片描述

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後臺對上傳的圖片進行壓縮

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章