在開發中,前端上傳的文件流,在後臺接口中通常是用MultipartFile類型的流格式接收,但是接收到的文件流往往不能滿足我們的使用要求,我們需要轉爲File類型的文件流再去讀取文件的寬高,大小等屬性進行壓縮上傳等操作。本工具類爲大家分享具體實現過程。接口規範:接收前端傳的文件流,以及指定的目標壓縮寬高,和壓縮完需要上傳到的指定目錄。
首先封裝一個動態生成文件目錄的文件路徑工具類
package com.demo.serverProvider.utils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
/**
* 創建時間:2019年2月15日 上午10:05:00
* 項目名稱:server-provider
* 類說明:文件上傳路徑生成
* @author guobinhui
* @since JDK 1.8.0_51
*/
public class UploadPathUtils {
/**
* 圖片最終生成的目錄結構:host(服務器域名或主機IP)+文件根目錄(虛擬目錄)+商品圖片目錄+日期目錄+圖片名稱(含後綴)
* 圖片最終存儲結構示例:http://10.220.146.3/uploadBaseDir/productPic/20190215/abc.jpg
* 注意:上傳業務處理時需要根據服務器系統是windows還是linux配置物理路徑和虛擬路徑的映射
*/
private final static SimpleDateFormat YYYY = new SimpleDateFormat("yyyy");
private final static SimpleDateFormat MM = new SimpleDateFormat("MM");
private final static SimpleDateFormat DD = new SimpleDateFormat("dd");
private static String getYear(Date date) {
if (null == date) {
date = new Date();
}
return YYYY.format(date);
}
private static String getMM(Date date) {
if (null == date) {
date = new Date();
}
return MM.format(date);
}
private static String getDD(Date date) {
if (null == date) {
date = new Date();
}
return DD.format(date);
}
/*按照日期格式動態生成日期目錄*/
private static String getDateDir() {
Date date = new Date();
StringBuilder path = new StringBuilder("/");
path.append(getYear(date));
path.append(getMM(date));
path.append(getDD(date));
return path.toString();
}
/*動態生成圖片上傳完整目錄(物理路徑)*/
public static String getPicUploadDir(int width,int height){
StringBuilder host = new StringBuilder(ImageConstants.WIN_IMAGE_ROOT_DIR);
host.append(ImageConstants.PRODUCT_PIC_DIR);
host.append(getDateDir());
String fullDir = generatorDir(host);
return fullDir;
}
/*動態生成目錄*/
private static String generatorDir(StringBuilder dir){
String fileDir = dir.toString();
if (!StringUtils.isEmpty(fileDir)) {
File file = new File(fileDir);
if (!file.isDirectory() && !file.exists()) {
file.mkdirs();
}
}
return fileDir;
}
}
下面代碼是具體的圖片按照指定寬高壓縮並上傳的具體實現過程的封裝
/**
* 壓縮圖片按照指定的寬高壓縮原圖
* @param img
* @param width
* @param height
* @param outputDir
*/
public static void thumbnail(MultipartFile file,int destWidth,int destHeight,String outputDir){
System.out.println("圖片壓縮開始");
long startTime = System.currentTimeMillis();
//得到上傳時的原文件名
String originalFilename = file.getOriginalFilename();
//獲取文件後綴名
String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
//獲取文件格式
String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
//獲取uuid作爲文件名
String name = UUID.randomUUID().toString().replaceAll("-", "");
String saveName = name + suffixName;
//存儲目錄
String picDir = UploadPathUtils.getPicUploadDir(destWidth,destHeight);
//圖片存儲全路徑
String outputPath = picDir + '/' + saveName;
OutputStream fos = null;
try {
//讀取源圖
BufferedImage BI = ImageIO.read(file.getInputStream());
double srcWidth = BI.getWidth(); // 源圖寬度
double srcHeight = BI.getHeight(); // 源圖高度
if ((int)srcWidth >= destWidth && (int)srcHeight >= destHeight) {
fos = new FileOutputStream(outputPath);
Image image = BI.getScaledInstance(destWidth, destHeight, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(destWidth, destHeight,BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.setColor(Color.RED);
g.drawImage(image, 0, 0, null); //繪製處理後的圖
g.dispose();
ImageIO.write(tag,ext,fos);
System.out.println("圖片壓縮並存儲結束");
long endTime = System.currentTimeMillis();
System.out.println("圖片壓縮共計耗時:" +(endTime-startTime)+"毫秒" );
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
歡迎各位開發者朋友一起交流。筆者電話(微信):18629374628