实战SSM_O2O商铺_08【商铺注册】Thumbnailator图片处理和封装工具类
文章目錄
- 概述
- Thumbnailator 簡介
- 工具類的封裝
- Step1 添加maven依賴
- Step2 FileUtil.java
- Step3 ImageUtil.java
- Github地址
概述
既然是o2o, 圖片是不可或缺的。
存儲(chǔ)這些圖片,一般的處理方式:放到專門圖片服務(wù)器或者在主機(jī)上單獨(dú)劃分目錄去存儲(chǔ)這些圖片。數(shù)據(jù)庫中的字段僅僅存放圖片的地址。 關(guān)于圖片的存放目錄,合理的情況在系統(tǒng)配置表中配置存儲(chǔ)的根目錄和各個(gè)模塊圖片存放的相對(duì)路徑, 便于應(yīng)用的遷移。
處理圖片的框架這里我們選擇Thumbnailator為圖片添加水印,為簡化圖片的處理,圖片工具類自然是不可或缺的。
Thumbnailator 簡介
Github地址: https://github.com/coobird/thumbnailator
Thumbnailator是一個(gè)用來生成圖像縮略圖的 Java類庫,可生成圖片縮略圖,支持根據(jù)一個(gè)目錄批量生成縮略圖,支持圖片縮放,區(qū)域裁剪,水印,旋轉(zhuǎn),保持比例等等
工具類的封裝
Step1 添加maven依賴
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator --> <dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version> </dependency>Step2 FileUtil.java
思路:
1. 設(shè)置文件存儲(chǔ)的根目錄
2. 項(xiàng)目中使用的圖片按照模塊和功能,設(shè)置存儲(chǔ)的相對(duì)路徑。
3. 圖片的絕對(duì)路徑: 根目錄+相對(duì)路徑
我們首先處理商鋪模塊,工具類會(huì)隨著項(xiàng)目的推進(jìn)而完善。
首先定義每個(gè)商鋪對(duì)應(yīng)的圖片,存儲(chǔ)在對(duì)應(yīng)shopId的目錄下。
package com.artisan.o2o.util;import java.io.File;import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** * * @ClassName: FileUtil* * @Description: 文件工具類* * @author: Mr.Yang* * @date: 2018年5月18日 下午11:32:05*/ public class FileUtil {private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);// 路徑分隔符. 在 類UNIX系統(tǒng)上為 '/',在 windows 系統(tǒng)上,它為 '\'private static String seperator = System.getProperty("file.separator");/*** * * @Title: getImgBasePath* * @Description: 根據(jù)不同的操作系統(tǒng),獲取圖片的存放路徑。* * 一般情況下都是將圖片存放到專門的圖片服務(wù)器或者主機(jī)上的其他目錄。* 而存放的目錄路徑,都是以配置項(xiàng)的形式存放在數(shù)據(jù)庫配置表中或者配置文件中。* * 這里為了簡單起見,我們直接將路徑硬編碼在代碼中。* * 圖片存儲(chǔ)的根路徑* @return* * @return: String*/public static String getImgBasePath() {String os = System.getProperty("os.name");logger.debug("os.name: {}", os);String basePath = "";if (os.toLowerCase().startsWith("win")) {basePath = "D:/o2o/image";} else {basePath = "/home/artisan/o2o/image";}// 根據(jù)操作系統(tǒng)的不同,使用當(dāng)前操作系統(tǒng)的路徑分隔符替換掉,我們寫的basePath中的路徑分隔符,當(dāng)然了也可以在basePath賦值的時(shí)候直接使用seperatorbasePath = basePath.replace("/", seperator);logger.debug("basePath: {}", basePath);return basePath;}/*** * * @Title: getShopImagePath* * @Description: 獲取特定商鋪的圖片的路徑,根據(jù)shopId來區(qū)分。理應(yīng)配置到數(shù)據(jù)庫配置表中或者配置文件中。* * 同樣的這里為了簡化操作,硬編碼* * 約定每個(gè)店鋪下的圖片分別存放在對(duì)應(yīng)的店鋪id下* * 圖片存儲(chǔ)的相對(duì)路徑.圖片最終存儲(chǔ)的位置需要加上getImgBasePath方法返回的basePath* * 數(shù)據(jù)庫tb_shop中的shop_img字段存儲(chǔ)的是該相對(duì)路徑,即該方法的返回值* * @param shopId* @return* * @return: String*/public static String getShopImagePath(long shopId) {String shopImgPath = "/upload/item/shopImage/" + shopId + "/";shopImgPath = shopImgPath.replace("/", seperator);logger.debug("shopImgPath: {}", shopImgPath);return shopImgPath;}/*** * * @Title: getWaterMarkFile* * @Description: 水印文件的位置。理應(yīng)配置到數(shù)據(jù)庫配置表中或者配置文件中。* * 同樣的這里為了簡化操作,硬編碼* * @return* * @return: File*/public static File getWaterMarkFile() {String basePath = FileUtil.getImgBasePath();String waterMarkImg = basePath + "/watermark/watermark.png";waterMarkImg = waterMarkImg.replace("/", seperator);logger.debug("waterMarkImg path: {}", waterMarkImg);return new File(waterMarkImg);}}Step3 ImageUtil.java
思路:
1. 圍繞添加水印輸出目標(biāo)圖片這個(gè)功能展開
2. 核心方法generateThumbnails ,創(chuàng)建縮略圖中3個(gè)關(guān)鍵參數(shù) 源圖片 水印圖 和 目標(biāo)圖片
3. 圍繞 源圖片 水印圖 和 目標(biāo)圖片,調(diào)用FileUtil中的方法組裝目標(biāo)圖片的存儲(chǔ)路徑以及目標(biāo)圖片的名稱。
4. 為了方便Service層做單元測(cè)試,詳見commonsMultipartFileToFile方法的說明
package com.artisan.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 net.coobird.thumbnailator.Thumbnails; import net.coobird.thumbnailator.geometry.Positions;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.multipart.commons.CommonsMultipartFile;public class ImageUtil {private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");private static final Random random = new Random();/*** * * @Title: commonsMultipartFileToFile* * @Description: 眾所周知,文件上傳spring使用CommonsMultipartFile來接收上傳過來的文件,* 而generateThumbnails方法中的第一個(gè)入?yún)⑽覀円呀?jīng)調(diào)整為了File* (主要是為了方便service層進(jìn)行單元測(cè)試* ,在service層無法初始化CommonsMultipartFile,只能在前端傳入的時(shí)候初始化* ,我們從底往上搭建項(xiàng)目,還不具備頁面,因此做了適當(dāng)?shù)母脑?#xff09;* * 需要將CommonsMultipartFile轉(zhuǎn)換為File* * @param cfile* * @return: File*/public File commonsMultipartFileToFile(CommonsMultipartFile cfile) {File file = null;try {// 獲取前端傳遞過來的文件名file = new File(cfile.getOriginalFilename());// 將cfile轉(zhuǎn)換為filecfile.transferTo(file);} catch (Exception e) {e.printStackTrace();logger.error("commonsMultipartFileToFile failed:{}", e.getMessage());}return file;}/*** * * @Title: generateThumbnails* * @Description: 處理縮略圖,并返回絕對(duì)路徑 (門面照以及商品的小圖)* * 舉例:shop的水印圖標(biāo)要存放在tb_shop的 shop_img字段,所以需要返回 水印圖標(biāo)所在的路徑* * * * @param file* 需要添加水印的文件* @param destPath* 添加水印后的文件的存放目錄* @return* * @return: String 返回相對(duì)路徑的好處是,項(xiàng)目一旦遷移,不會(huì)影響,只需要變更basePath即可,盡可能少改動(dòng)。* 圖片存儲(chǔ)的絕對(duì)路徑=basePath+該路徑*/public static String generateThumbnails(File file, String destPath) {// 拼接后的新文件的相對(duì)路徑String relativeAddr = null;try {// 1.為了防止圖片的重名,不采用用戶上傳的文件名,系統(tǒng)內(nèi)部采用隨機(jī)命名的方式String fileName = generateRandomFileName();// 2.獲取用戶上傳的文件的擴(kuò)展名,用于拼接新的文件名String fileExtensionName = getFileExtensionName(file);// 3.校驗(yàn)?zāi)繕?biāo)目錄是否存在,不存在創(chuàng)建目錄validateDestPath(destPath);// 4.拼接新的文件名relativeAddr = destPath + fileName + fileExtensionName;logger.info("圖片相對(duì)路徑 {}", relativeAddr);// 絕對(duì)路徑的形式創(chuàng)建文件String basePath = FileUtil.getImgBasePath();File destFile = new File(basePath + relativeAddr);logger.info("圖片完整路徑 {}", destFile.getAbsolutePath());// 5.給源文件加水印后輸出到目標(biāo)文件Thumbnails.of(file).size(500, 500).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(FileUtil.getWaterMarkFile()), 0.25f).outputQuality(0.8).toFile(destFile);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("創(chuàng)建水印圖片失敗:" + e.toString());}return relativeAddr;}/*** * * @Title: generateRandomFileName* * @Description: 系統(tǒng)時(shí)間+5位隨機(jī)數(shù)字* * @param file* @return* * @return: String*/private static String generateRandomFileName() {String sysdate = sdf.format(new Date());// 5位隨機(jī)數(shù) 10000到99999之間 ,下面的取值[ 包括左邊,不包括右邊 ],滿足10000到99999int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;String randomFileName = sysdate + rannum;logger.debug("fileName: {}", randomFileName);return randomFileName;}/*** * * @Title: getFileExtensionName* * @Description: 獲取文件的擴(kuò)展名* * @param file* * @return: String*/private static String getFileExtensionName(File file) {String fileName = file.getName();String extension = fileName.substring(fileName.lastIndexOf("."));logger.debug("extension: {}", extension);return extension;}/*** * * @Title: validateDestPath* * @Description:* * @param targetAddr* 圖片上傳的相對(duì)路徑* * @return: void*/private static void validateDestPath(String targetAddr) {// 獲取絕對(duì)路徑String realFileParentPath = FileUtil.getImgBasePath() + targetAddr;// 不存在的話,逐級(jí)創(chuàng)建目錄File dirPath = new File(realFileParentPath);if (!dirPath.exists()) {dirPath.mkdirs();}}/*** * * @Title: main* * @Description: 演示thumbnail的基本用法* * @param args* * @return: void*/public static void main(String[] args) {try {// 需要加水印的圖片File souceFile = new File("D:/o2o/artisan.jpg");// 加完水印后輸出的目標(biāo)圖片File destFile = new File("D:/o2o/artisan-with-watermark.jpg");// 水印圖片File warterMarkFile = FileUtil.getWaterMarkFile();logger.info("warterMarkFileName: {}", warterMarkFile.getName());// 加水印Thumbnails.of(souceFile).size(500, 500).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(warterMarkFile), 0.25f).outputQuality(0.8).toFile(destFile);logger.info("水印添加成功,帶有水印的圖片{}", destFile.getAbsolutePath());generateRandomFileName();getFileExtensionName(souceFile);} catch (IOException e) {e.printStackTrace();throw new RuntimeException("創(chuàng)建縮略圖失敗:" + e.toString());}} }Github地址
代碼地址: https://github.com/yangshangwei/o2o
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的实战SSM_O2O商铺_08【商铺注册】Thumbnailator图片处理和封装工具类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实战SSM_O2O商铺_07【商铺注册】
- 下一篇: 实战SSM_O2O商铺_09【商铺注册】