天天看點

壓縮上傳的圖檔并傳回圖檔路徑

由于現在手機像素普遍較高,随手拍一張圖檔都6、7M,十幾兆的圖檔也并不罕見。如果這些未處理的圖檔直接随資料上傳向伺服器,不但會占用更多的存儲空間,而且使用者也要等更久的時間,體驗性會差很多,同時更長的傳輸時間,也加大了問題發生的機率,直接決定了系統的生命力,可謂是生死攸關,基于這些情況,壓縮圖檔并上傳的需求應運而生。

壓縮上傳的圖檔并傳回圖檔路徑

開源位元組使用Thumbnails去掉圖檔備援資訊,有效壓縮圖像,同時又不會損害圖像效果。同時直接傳回圖檔路徑,友善前台調用。代碼如下:

/**
 * 通用上傳請求
 */
@PostMapping("/common/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
    try
    {
        // 真實檔案名
        String realName = file.getOriginalFilename();
        // 上傳檔案路徑
        String filePath = RuoYiConfig.getUploadPath();
        // 上傳并傳回新檔案名稱
        String fileName = FileUploadUtils.upload(filePath, file);
        String url = domain + fileName;
        AjaxResult ajax = AjaxResult.success();
        ajax.put("fileName", fileName);
        ajax.put("realName", realName);
        ajax.put("url", url);
        return ajax;
    }
    catch (Exception e)
    {
        return AjaxResult.error(e.getMessage());
    }
}

/**
 * 檔案上傳
 *
 * @param baseDir 相對應用的基目錄
 * @param file 上傳的檔案
 * @param allowedExtension 上傳檔案類型
 * @return 傳回上傳成功的檔案名
 * @throws FileSizeLimitExceededException 如果超出最大大小
 * @throws FileNameLengthLimitExceededException 檔案名太長
 * @throws IOException 比如讀寫檔案出錯時
 * @throws InvalidExtensionException 檔案校驗異常
 */
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
        throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
        InvalidExtensionException
{
    int fileNamelength = file.getOriginalFilename().length();
    if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
    {
        throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
    }
    assertAllowed(file, allowedExtension);
    String fileName = extractFilename(file);
    File desc = getAbsoluteFile(baseDir, fileName);
    // 如果是圖檔,則壓縮
    if (ImageCheck(file))
    {
        // 圖檔大小;其中file.length()擷取的是位元組,除以1024可以得到以kb為機關的檔案大小
        long size = file.getSize() / DEFAULT_SIZE;
        // 圖檔對象
        BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
        // 圖檔寬度
        int width = bufferedImage.getWidth();
        // 使用Thumbnailator實作圖檔壓縮,通過大小與尺寸的判斷,保證圖檔最優
        float scale = 1f;
        float quality = 1f;
        // 如果像素寬度大于3000,則縮放到原圖一半大小,否則不改變尺寸
        if(width > 3000){
            scale = 0.5f;
        }
        // 如果像素寬度大于1500,則縮放到原圖80%大小,否則不改變尺寸
        if(width > 1500){
            scale = 0.8f;
        }
        // 如果圖檔大于5000kb,則壓縮到原圖的50%品質
        if(size > 5000){
            quality = 0.5f;
        }
        // 如果圖檔大于1000kb,則壓縮到原圖的80%品質
        if(size > 1000){
            quality = 0.8f;
        }
        // 去掉圖檔備援資訊後可以有效壓縮圖像,同時又不會損害圖像的有效資訊。
        Thumbnails.of(file.getInputStream())
            .scale(scale) // 值在0到1之間,1f就是原圖大小,0.5就是原圖的一半大小
            .outputQuality(quality) // 值也是在0到1,越接近于1品質越好,越接近于0品質越差
            .toFile(desc);
    }else{
        file.transferTo(desc);
    }
    String pathFileName = getPathFileName(baseDir, fileName);
    return pathFileName;
}      

繼續閱讀