一、 将图片改变大小、加水印、压缩、输出在同级目录下

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");
	}
}

4-3 Thumbnailator图片处理和封装Util

1 读取文件的路径

2 尺寸

3 水印在右下角

4 读入水印的图片流

5 透明度

6 压缩比

7 输出路径

 

二、地址处理--编写工具类

图片保存路径不在classpath 下的原因:

4-3 Thumbnailator图片处理和封装Util

因为当工程重新部署时,新生成的图片会被删除掉。因此需要将图片的根路径设置在工程以外

因此创建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、先将思路按方法名写出来,再实现该方法名

4-3 Thumbnailator图片处理和封装Util

 2、日期的写法:先用SimpleDateFormat定义日期的格式,再用它的format方法对当前日期进行格式化

4-3 Thumbnailator图片处理和封装Util

 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是比较简单的

 

4-3 Thumbnailator图片处理和封装Util

 

因此要将CommonsMultipartFile改为File

4-3 Thumbnailator图片处理和封装Util

因为这个函数把 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;
	}

 

相关文章: