SSM开发笔记4-1图片存储及地址获取

一、自动根据系统获取文件路径存储路径的工具类(图片的根路径和图片的子路径)PathUtil

package com.imooc.o2o.util;

public class PathUtil {
	private static String seperator = System.getProperty("file.separator");
	// 1、设置根据系统不同存储不同的位置
	public static String getImgBasePath() {
		String os = System.getProperty("os.name");
		String basePath = "";
		if (os.toLowerCase().startsWith("win")) {
			basePath = "D:/projectdev/image";
		} else {
			basePath = "/Users/baidu/work/image";
		}
		// 2、对获取到的路径进行格式统一
		basePath = basePath.replace("/", seperator);
		// 3、返回存储路径
		return basePath;
	}

	// 4、图片存储的子路径
	public static String getShopImagePath(long shopId) {
		String imagePath = "/upload/images/item/shop/" + shopId + "/";
		return imagePath.replace("/", seperator);
	}
}

二、图片处理的工具类 ImageUtil

       1、图片加水印
       2、缩略图处理
       3、生成随机文件名
       4、获取文件扩展名
       5、创建目标路径所涉及到的目录
       6、返回相对路径的目的是:我们是通过pathutil工具类自动获取文件存储地址的,当我们项目迁移,我们只需要修改pathutil的路径即可,不用修改数据库中保存的数据,极大的方便了项目的迁移

package com.imooc.o2o.util;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.imooc.o2o.dto.ImageHolder;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

public class ImageUtil {
	private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
	private static final Random r = new Random();
	private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);

	/**
	 * 将CommonsMultipartFile转换成File类
	 * 
	 * @param cFile
	 * @return
	 */
	public static File transferCommonsMultipartFileToFile(CommonsMultipartFile cFile) {
		File newFile = new File(cFile.getOriginalFilename());
		try {
			cFile.transferTo(newFile);
		} catch (IllegalStateException e) {
			logger.error(e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.toString());
			e.printStackTrace();
		}
		return newFile;
	}

	/**
	 * 处理缩略图,并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("basePath is :" + basePath);
		// 调用Thumbnails生成带有水印的图片
		try {
			Thumbnails.of(thumbnail.getImage()).size(200, 200)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f)
					.outputQuality(0.8f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩略图失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

	/**
	 * 处理详情图,并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		// 调用Thumbnails生成带有水印的图片
		try {
			Thumbnails.of(thumbnail.getImage()).size(337, 640)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f)
					.outputQuality(0.9f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩图片失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

	/**
	 * 创建目标路径所涉及到的目录,即/home/work/xiangze/xxx.jpg, 那么 home work xiangze
	 * 这三个文件夹都得自动创建
	 * 
	 * @param targetAddr
	 */
	private static void makeDirPath(String targetAddr) {
		String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
		File dirPath = new File(realFileParentPath);
		if (!dirPath.exists()) {
			dirPath.mkdirs();
		}
	}

	/**
	 * 获取输入文件流的扩展名
	 * 
	 * @param thumbnail
	 * @return
	 */
	private static String getFileExtension(String fileName) {
		return fileName.substring(fileName.lastIndexOf("."));
	}

	/**
	 * 生成随机文件名,当前年月日小时分钟秒钟+五位随机数
	 * 
	 * @return
	 */
	public static String getRandomFileName() {
		// 获取随机的五位数
		int rannum = r.nextInt(89999) + 10000;
		String nowTimeStr = sDateFormat.format(new Date());
		return nowTimeStr + rannum;
	}

	public static void main(String[] args) throws IOException {
		Thumbnails.of(new File("/Users/baidu/work/image/xiaohuangren.jpg")).size(200, 200)
				.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f)
				.outputQuality(0.8f).toFile("/Users/baidu/work/image/xiaohuangrennew.jpg");
	}

	/**
	 * storePath是文件的路径还是目录的路径, 如果storePath是文件路径则删除该文件,
	 * 如果storePath是目录路径则删除该目录下的所有文件
	 * 
	 * @param storePath
	 */
	public static void deleteFileOrPath(String storePath) {
		File fileOrPath = new File(PathUtil.getImgBasePath() + storePath);
		if (fileOrPath.exists()) {
			if (fileOrPath.isDirectory()) {
				File files[] = fileOrPath.listFiles();
				for (int i = 0; i < files.length; i++) {
					files[i].delete();
				}
			}
			fileOrPath.delete();
		}
	}
}

三、图片工具类的使用

       1、前端通过图片上传控件上传图片

①不同的前端工具,上传控件不同,以此为例
<input type="file" id="shop-img">
②获取上传的图片文件流
var shopImg = $('#shop-img')[0].files[0];
③将图片文件流通过formData 
//生成表单对象,用于接收参数并传递给后台
var formData = new FormData();
// 添加图片流进表单对象里
formData.append('shopImg', shopImg);
④通过ajax方式传输到后台,也可以直接通过form表单的形式提交
$.ajax({
	url : (isEdit ? editShopUrl : registerShopUrl),
	type : 'POST',
	data : formData,
	contentType : false,
	processData : false,
	cache : false,
	success : function(data) {
		if (data.success) {
			$.toast('提交成功!');
			if (!isEdit) {
				// 若为注册操作,成功后返回店铺列表页
				window.location.href = "/o2o/shopadmin/shoplist";
			}
		} else {
			$.toast('提交失败!' + data.errMsg);
		}
		// 点击验证码图片的时候,注册码会改变
		$('#captcha_img').click();
	}
});

       2、后端从request中剥离图片,文件流转换成java.io.file

CommonsMultipartFile shopImg = null;
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if (commonsMultipartResolver.isMultipart(request)) {
	MultipartHttpServletRequest multipartHttpServletRequest =(MultipartHttpServletRequest) request;
	shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");//参数中的shopImg是前端原定好的名称
} else {
	modelMap.put("success", false);
	modelMap.put("errMsg", "上传图片不能为空");
	return modelMap;
}

       3、对图片进行存储
              ①定义图片属性类

package com.imooc.o2o.dto;

import java.io.InputStream;

public class ImageHolder {

	private String imageName;
	private InputStream image;

	public ImageHolder(String imageName, InputStream image) {
		this.imageName = imageName;
		this.image = image;
	}

	public String getImageName() {
		return imageName;
	}

	public void setImageName(String imageName) {
		this.imageName = imageName;
	}

	public InputStream getImage() {
		return image;
	}

	public void setImage(InputStream image) {
		this.image = image;
	}

}

              ②存储

//File是能直接通过读取路径产生文件流inputStream
//文件名是为了generateThumbnail中通过文件名获取其扩展名
private void addShopImg(Shop shop, ImageHolder thumbnail) {
	// 获取shop图片目录的相对值路径
	String dest = PathUtil.getShopImagePath(shop.getShopId());
	String shopImgAddr = ImageUtil.generateThumbnail(thumbnail, dest);
	shop.setShopImg(shopImgAddr);
}

以上代码详情可见o2o项目源码

发布了26 篇原创文章 · 获赞 1 · 访问量 762

猜你喜欢

转载自blog.csdn.net/Kasey_L/article/details/105080063
4-1