最近一直在網上找關于圖片上傳、旋轉處理、壓縮處理等相關的資料,發現也不是很多。首先圖片處理還是挺復雜的,完全靠自己寫代碼實現,筆者感覺自己不具備這個實力,所以還是在網上找一些好的插件,然后綜合下,節省時間。 記得在上一篇博文就介紹了圖片上傳的方案,今天就來說說圖片旋轉和壓縮處理。因為這兩點還是挺重要的,之所以會處理旋轉這個問題,是由于ios拍照存在這個bug,導致上傳的圖片方向逆時針旋轉了90。那么,怎么解決呢?其實,上篇博文所使用的兩個前端插件都解決了旋轉的問題,所以這個就不用擔心了,雖然在后臺也可以處理,但是還是比較麻煩的,大家可以去研究下。壓縮的話,由于圖片太大了,不壓縮使用,會導致加載圖片太慢。那么是在后臺處理,還是前端處理呢?這一點我也不太清楚,需要結合性能和兼容性去選擇。由于thumbnailator這個后臺插件封裝了對圖片相關的處理,所以筆者就選用這個插件了,比較方便,下面筆者就來進行介紹。
筆者把代碼封裝到了一個工具類中,如下:
package com.qiyongkang.sys.util;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import com.drew.imaging.ImageMetadataReader;import com.drew.metadata.Directory;import com.drew.metadata.Metadata;import com.drew.metadata.exif.ExifIFD0Directory;import net.coobird.thumbnailator.Thumbnails;/** * * ClassName: ImageUtil <br/> * Function: 圖片處理. <br/> * date: 2017年2月6日 下午1:49:15 <br/> * * @author qiyongkang * @version * @since JDK 1.6 */public class ImageUtil { PRivate static Logger logger = LogManager.getLogger(ImageUtil.class); //寬 public static int IMAGE_WIDTH = 1; //高 public static int IMAGE_HEIGHT = 2; //方向 public static int ORIENTATION_ONE = 1; //正常 public static int ORIENTATION_THREE = 3; //180 public static int ORIENTATION_SIX = 6; //順時針90 public static int ORIENTATION_EIGHT = 8; //逆時針90,順時針270 /** * * getImageSize: 獲取圖片大小. <br/> * * @author qiyongkang * @return * @since JDK 1.6 */ public static int getImageSize(File file, int flag) { int size = 0; if (file == null || !file.exists()) return size; try { if (IMAGE_WIDTH == flag) { size = ImageIO.read(file).getWidth(); } else if (IMAGE_HEIGHT == flag) { size = ImageIO.read(file).getHeight(); } } catch (IOException e) { logger.error("獲取圖片的大小異常", e); e.printStackTrace(); } return size; } /** * * getImageOrientation: 獲取圖片的方向 <br/> * * @author qiyongkang * @param file * @return * @since JDK 1.6 */ public static int getImageOrientation(File file) { int orientation = ORIENTATION_ONE; try { Metadata metadata = ImageMetadataReader.readMetadata(file); Directory dr = metadata.getDirectory(ExifIFD0Directory.class); if (dr == null) { logger.info("沒有方向信息"); return orientation; } orientation = dr.getInt(ExifIFD0Directory.TAG_ORIENTATION); logger.info("orientation:" + orientation); } catch (Exception e) { logger.error("獲取圖片的方向異常", e); e.printStackTrace(); } return orientation; } /** * * rotateImage: 旋轉圖片到正常的方向. <br/> * * @author qiyongkang * @since JDK 1.6 */ public static void rotateImage(File file) { //計算方向 int orientation = getImageOrientation(file); double angle = 0d; if (orientation > ORIENTATION_ONE) { //進行圖片處理 switch (orientation) { case 3: //需要旋轉180度 angle = 180d; break; case 6: //需要旋轉270度 angle = 270d; break; case 8: //需要旋轉90度 angle = 90d; break; } } try { Thumbnails.of(file).scale(1).rotate(angle).toFile(file);; } catch (IOException e) { logger.error("旋轉圖片異常", e); e.printStackTrace(); } } /** * * impressImage: 壓縮圖片. <br/> * * @author qiyongkang * @param file * @param width * @param height * @since JDK 1.6 */ public static void impressImage(File file, int width, int height) { try { Thumbnails.of(file).size(width, height).toFile(file); } catch (IOException e) { e.printStackTrace(); logger.error("壓縮圖片異常:" + e); } } public static void main(String[] args) { File file = new File("C://Users//qiyongkang//Desktop//測試圖片//17251486371832020.jpg");// rotateImage(file); System.out.println("圖片的方向:" + getImageOrientation(file)); }}在上一篇博文已經貼出了上傳的代碼,這里就是加了點壓縮處理的代碼,如下:
/** * Project Name:qyk_testSpringMVC * File Name:FileController.java * Package Name:com.qiyongkang.sys.controller * Date:2016年11月6日下午3:12:05 * Copyright (c) 2016, Thinkive(http://www.thinkive.com/) All Rights Reserved. **/package com.qiyongkang.sys.controller;import java.io.File;import java.util.Date;import java.util.Iterator;import java.util.List;import javax.servlet.http.HttpServletRequest;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.commons.io.FileUtils;import org.apache.commons.io.FilenameUtils;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.qiyongkang.sys.dto.ExtJsObject;import com.qiyongkang.sys.util.ImageUtil;/** * ClassName:FileController <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2016年11月6日 下午3:12:05 <br/> * * @author qiyongkang * @version * @since JDK 1.6 * @see */@Controller@RequestMappingpublic class FileController { /** * 日志類 */ private static Logger log = LogManager.getLogger(FileController.class); private String tempPath = "/uploadImageTemp";// 臨時存儲目錄 private String savePath = "/userImage";// 存儲目錄 private String fileName = ""; // 文件名 private static int PICTURE_WIDTH = 100; //壓縮成的寬度 @RequestMapping @ResponseBody public ExtJsObject uploadImage(HttpServletRequest request) { ExtJsObject extJsObject = new ExtJsObject(); try { // 獲取臨時目錄 String tempPathDir = request.getsession().getServletContext().getRealPath(this.tempPath); File tempPathDirFile = new File(tempPathDir); if (!tempPathDirFile.exists()) { tempPathDirFile.mkdirs(); } // 存儲目錄 String realDir = request.getSession().getServletContext().getRealPath(this.savePath); File realDirFile = new File(realDir); if (!realDirFile.exists()) { realDirFile.mkdirs(); } // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // Set factory constraints factory.setSizeThreshold(4096); // 設置緩沖區大小,這里是4kb factory.setRepository(tempPathDirFile);// 設置緩沖區目錄 // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Set overall request size constraint upload.setSizeMax(4194304); // 設置最大文件尺寸,這里是4MB List<FileItem> items = upload.parseRequest(request);// 得到所有的文件 Iterator<FileItem> i = items.iterator(); while (i.hasNext()) { FileItem fi = (FileItem) i.next(); String fileName = fi.getName(); if (fileName != null) { // 這里加一個限制,如果不是圖片格式,則提示錯誤. (gif,jpg,jpeg,bmp,png) String suffixName = FilenameUtils.getExtension(fileName); if ("gif".equalsIgnoreCase(suffixName) || "jpg".equalsIgnoreCase(suffixName) || "jpeg".equalsIgnoreCase(suffixName) || "bmp".equalsIgnoreCase(suffixName) || "png".equalsIgnoreCase(suffixName)) { // 文件名 this.fileName = new Date().getTime() + "." + FilenameUtils.getExtension(fileName); File savedFile = new File(realDir, this.fileName); fi.write(savedFile); // 小圖片 File savedSmallFile = new File(realDir + "/small/", this.fileName); FileUtils.copyFile(savedFile, savedSmallFile); //壓縮一把 ImageUtil.impressImage(savedSmallFile, PICTURE_WIDTH, PICTURE_WIDTH); } else { extJsObject.setSuccess(false); extJsObject.setMsg("非圖片格式,請重新上傳!"); } } } extJsObject.setSuccess(true); extJsObject.setMsg("上傳成功!"); extJsObject.setResult(this.fileName); } catch (Exception e) { extJsObject.setSuccess(false); extJsObject.setMsg("上傳失敗!"); log.error("圖片上傳失敗", e); } return extJsObject; }}好了,就介紹到這了,用起來還是比較簡單的,大家可以去試試,同時也歡迎分享更好的方式!
新聞熱點
疑難解答