由于現在手機像素普遍較高,随手拍一張圖檔都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;
}