一、 将图片改变大小、加水印、压缩、输出在同级目录下
1、在pom.xml中引入依赖
<!-- 图片处理 -->
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2、在com.imooc.o2o.util下创建ImageUtil
/**
* 将图片改变大小、加水印、压缩、输出在同级目录下
*/
public class ImageUtil {
public static void main(String[] args) throws IOException {
//获取classPath的绝对值路径
String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
Thumbnails.of(new File("/Users/shawn/Document/实战练习/image/xiaohuangren.jpg"))
.size(200,200).watermark(Positions.BOTTOM_RIGHT,ImageIO.read(new File(basePath + "/watermark.jpg")),0.25f)
.outputQuality(0.8f).toFile("/Users/shawn/Document/实战练习/image/xiaohuangrennew.jpg");
}
}
1 读取文件的路径
2 尺寸
3 水印在右下角
4 读入水印的图片流
5 透明度
6 压缩比
7 输出路径
二、地址处理--编写工具类
图片保存路径不在classpath 下的原因:
因为当工程重新部署时,新生成的图片会被删除掉。因此需要将图片的根路径设置在工程以外
因此创建PathUtil.java 工具类
这里值得学习的是不同系统有不同的分隔符,我们写路径时先按传统的方式写,再获取系统的分隔符进行替换。
public class PathUtil {
private static String seperator = System.getProperty("file.separator");//获得系统的分隔符
/**
* 返回项目图片的根路径
* @return
*/
public static String getImgBasePath() {
String os = System.getProperty("os.name");//os.name是固定参数,表示获取系统名称
String basePath = "";
if(os.toLowerCase().startsWith("win")) {
basePath = "D:/project/image/";
} else {
basePath = "/Users/shawn/Document/实战练习/image/";
}
basePath = basePath.replace("/", seperator);//确保该路径在不同系统下都是有效的
return basePath;
}
/**
* 获取店铺图片的相对子路径(将图片分别存储在各自店铺的路径下),因此传入shopId加以区分
* @return
*/
public static String getShopImagePath(long shopId) {
String imagePath = "/upload/item/shop/"+shopId+"/";
return imagePath.replace("/", seperator);
}
}
三、改进ImageUtil.java
值得学习:
1、先将思路按方法名写出来,再实现该方法名
2、日期的写法:先用SimpleDateFormat定义日期的格式,再用它的format方法对当前日期进行格式化
3、获取输入文件流的扩展名
private static String getFileExtension(CommonsMultipartFile cFile) {
//获取最后的点号后的字符
String orginalFileName = cFile.getOriginalFilename();
return orginalFileName.substring(orginalFileName.lastIndexOf("."));
}
4、创建目标路径上涉及到的目录
mkdirs() 和mkdir()不同,是创建涉及到的所有的文件夹
private static void makeDirPath(String targetAddr) {
//targetAddr是相对路径,因此要获取它的绝对路径
String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
File dirPath = new File(realFileParentPath);
if(!dirPath.exists()) {
dirPath.mkdirs();
}
}
此外注意:
spring会将前台传来的文件用MultipartFile的接口去处理,这个接口有一个实现类是CommonsMultipartFile,而无法接收我们单元测试里面直接写好路径的文件,需要通过file来接收。查看源码,发现传入参数的初始化是用FileItem进行的,而不是Java.io,将Java.io.File转换为CommonsMultipartFile是很困难的,因此不能将ava.io.File转换进来。
但将CommonsMultipartFile转换为Java.io.File是比较简单的
因此要将CommonsMultipartFile改为File
因为这个函数把 CommonsMultipartFile改为File了,所以要在这个函数之前写一个函数将 CommonsMultipartFile转换为File
/**
* 将CommonsMultipartFile转换成File
* @param cFile
* @return
*/
public static File transferCommonsMultipartFileToFile(CommonsMultipartFile cFile) {
File newFile = new File(cFile.getOriginalFilename());
try {
cFile.transferTo(newFile);//将cFile的文件流写入到新创建的文件newFile里
} catch (IllegalStateException e) {
logger.error(e.toString());
e.printStackTrace();
} catch (IOException e) {
logger.error(e.toString());
e.printStackTrace();
}
return newFile;
}