在开发中,前端上传的文件流,在后台接口中通常是用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