基於SpringBoot的圖片上傳元件,實現圖片裁剪、Thumbnailator壓縮的功能
阿新 • • 發佈:2019-01-22
本週三、週四、週五封裝了一個基於SpringBoot的圖片上傳元件。功能流程如下:
1、前臺頁面有一個“選擇檔案”按鈕,點選選擇一張圖片後,在前臺介面進行顯示。
2、雙擊顯示出來的圖片,前臺使用cropper圖片裁剪外掛,將裁剪資訊(裁剪起始點座標 x,y,裁剪寬度width,裁剪高度height)以及上傳的圖片檔案,傳給後臺。
3、後臺對圖片進行裁剪,再將裁剪後的圖片進行壓縮,把原圖路徑、裁剪後圖片路徑、壓縮後圖片路徑、base64編碼存入資料庫。(同時後臺將這三種圖片儲存到本地 D:/images/ 路徑下)
4、後臺將壓縮後的圖片路徑傳給前臺。
5、前臺接收到這個路徑,在頁面上進行顯示。由於此時顯示的是壓縮的圖片,如果使用者想看原圖(裁剪後圖片的原圖),點選該圖片,攜帶這個圖片路徑請求後臺介面。
6、後臺接收到壓縮圖片路徑,select資料庫,找到裁剪後圖片路徑,返回給前臺。
7、前臺接收到這個原圖片路徑,在頁面進行顯示。
一、SpringBoot自定義靜態資源對映
將一些動態維護的檔案,放在伺服器磁碟的某個目錄下(專案目錄之外),並且通過SpringBoot服務進行訪問。
實現類繼承WebMvcConfigurerAdapter並重寫方法addResourceHandlers,將磁碟上檔案存放的絕對路徑對映,就可以通過訪問SpringBoot服務來訪問檔案了。
- @Configuration
- public class WebAppConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/myImages/**").addResourceLocations("file:D:/images/");
- super.addResourceHandlers(registry);
- }
- }
假如在D盤images目錄下有一個test.jpg圖片,那麼通過訪問 http://localhost:8080/myImages/test.jpg
二、Java實現圖片裁剪、使用Thumbnailator工具對圖片進行壓縮。
height。
1、controller層程式碼:
- /**
- * 影象切割(按指定起點座標和寬高切割)
- * @param file 源影象檔案
- * @param x 目標切片起點座標X
- * @param y 目標切片起點座標Y
- * @param width 目標切片寬度
- * @param height 目標切片高度
- */
- @RequestMapping(value = "/cutImage", method = RequestMethod.POST, headers = "Accept=application/json")
- @ResponseBody
- public HttpResponseEntity cutImage(MultipartFile file,
- int x, int y, int width, int height) {
- HttpResponseEntity httpResponseEntity = new HttpResponseEntity();
- try {
- String strResult = imgUploadService.cutImage(file, x, y, width, height);
- httpResponseEntity.setMessage("成功");
- httpResponseEntity.setCode("200");
- httpResponseEntity.setData(strResult);
- } catch (Exception e) {
- e.printStackTrace();
- httpResponseEntity.setCode("602");
- httpResponseEntity.setMessage("失敗");
- }
- return httpResponseEntity;
- }
在本方法中使用uuid為圖片重新命名。
在本方法中實現了對圖片的裁剪、等比例壓縮。此處壓縮使用的是Thumbnailator工具,壓縮質量很高。但是按照
Thumbnails.of(new_path_img) .scale(1f)//圖片長寬大小 .outputQuality(0.1f)//圖片質量 .toFile(compress_img_path);這個方法實現的壓縮,記憶體大小依舊很大。
- @Override
- /**
- * @param srcFile原始檔
- * @param outFile輸出檔案
- * @param x座標
- * @param y座標
- * @param width寬度
- * @param height高度
- * @描述 —— 裁剪圖片
- */
- public String cutImage(MultipartFile file, int x, int y, int width, int height) throws IOException {
- //得到上傳時的檔名
- String filename = file.getOriginalFilename();
- //獲取檔案字尾名
- String suffixName = filename.substring(filename.lastIndexOf("."));
- //獲取uuid作為檔名
- String name = UUIDUtil.getOneUUID();
- filename = name + suffixName;
- //儲存地址
- String filePath = "D:/images/";
- //圖片路徑
- String path_img = filePath + filename;
- File dest = new File(path_img);
- if (!dest.getParentFile().exists()) {
- dest.getParentFile().mkdirs();
- }
- try {
- file.transferTo(dest);
- } catch (IOException e) {
- e.printStackTrace();
- }
- ImgUploadEntity imgUploadEntity = new ImgUploadEntity();
- imgUploadEntity.setImgPath(filename);
- FileInputStream is = null;
- ImageInputStream iis = null;
- try {
- // 如果源圖片不存在
- if (!new File(path_img).exists()) {
- return"失敗";
- }
- // 讀取圖片檔案
- is = new FileInputStream(path_img);
- // 獲取檔案格式
- String ext = path_img.substring(path_img.lastIndexOf(".") + 1);
- // ImageReader解碼指定格式
- Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext);
- ImageReader reader = it.next();
- // 獲取圖片流
- iis = ImageIO.createImageInputStream(is);
- // 輸入源中的影象將只按順序讀取
- reader.setInput(iis, true);
- // 描述如何對流進行解碼
- ImageReadParam param = reader.getDefaultReadParam();
- // 圖片裁剪區域
- Rectangle rect = new Rectangle(x, y, width, height);
- // 提供一個 BufferedImage,將其用作解碼畫素資料的目標
- param.setSourceRegion(rect);
- // 使用所提供的 ImageReadParam 讀取通過索引 imageIndex 指定的物件
- BufferedImage bi = reader.read(0, param);
- // 儲存新圖片
- String name1 = UUIDUtil.getOneUUID();
- String newFileName = name1 + suffixName;
- String new_path_img = filePath + newFileName;
- File tempOutFile = new File(new_path_img);
- if (!tempOutFile.exists()) {
- tempOutFile.mkdirs();
- }
- ImageIO.write(bi, ext, tempOutFile);
- imgUploadEntity.setNewImgPath(newFileName);
- //為壓縮後圖片建立路徑
- String compressImgPath = UUIDUtil.getOneUUID() + suffixName;
- String compress_img_path = filePath + compressImgPath;
- //等比壓縮圖片,使用Java
- // boolean flag = compressImg(new_path_img, compress_img_path,100,100,true);
- /*
- * 壓縮圖片,使用Thumbnails工具
- * 先判斷圖片大小,如果小於50 kb(51200位元組)不進行壓縮
- * file.length()方法最大隻能獲取2g的檔案大小,但是前臺傳給後臺圖片最大為10M,所以此處不必擔心
- */
- if(tempOutFile.length() < 51200){