Java後端上傳手機拍攝圖片矯正方向
阿新 • • 發佈:2019-01-02
package useractivity.utils; import com.drew.imaging.ImageMetadataReader; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; import com.drew.metadata.exif.ExifDirectoryBase; import org.apache.log4j.Logger; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.HashMap; import java.util.Map; /** * @author leo * @version 2018/11/28 11:01 * @Description 矯正手機拍攝圖片方向問題 */ public class RotateImage { private static Logger logger = Logger.getLogger(RotateImage.class); /** * 調整手機上傳的圖片方向 * * @param userHeadImage * @param userHeadImage * @return */ public static Map rotate(MultipartFile userHeadImage) { Image src = null; int angel = 0; try { src = ImageIO.read(userHeadImage.getInputStream()); File file = File.createTempFile("tmp", null); userHeadImage.transferTo(file); file.deleteOnExit(); angel = getRotateAngleForPhoto(file); } catch (IOException e) { e.printStackTrace(); } Map<String, Object> result = new HashMap<>(); int src_width = src.getWidth(null); int src_height = src.getHeight(null); // calculate the new image size Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension( src_width, src_height)), angel); BufferedImage res = null; res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = res.createGraphics(); // transform g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2); g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2); g2.drawImage(src, null, null); ByteArrayOutputStream bs = new ByteArrayOutputStream(); try { ImageOutputStream imOut = ImageIO.createImageOutputStream(bs); //scaledImage1為BufferedImage,jpg為影象的型別 ImageIO.write(res, "jpg", imOut); } catch (IOException e) { e.printStackTrace(); } logger.info("轉換工具類中圖片大小" + bs.size()); InputStream is = new ByteArrayInputStream(bs.toByteArray()); result.put("is", is); result.put("size", bs.size()); return result; } public static Rectangle CalcRotatedSize(Rectangle src, int angel) { // if angel is greater than 90 degree, we need to do some conversion if (angel >= 90) { if (angel / 90 % 2 == 1) { int temp = src.height; src.height = src.width; src.width = temp; } angel = angel % 90; } double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2; double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r; double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2; double angel_dalta_width = Math.atan((double) src.height / src.width); double angel_dalta_height = Math.atan((double) src.width / src.height); int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width)); int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height)); int des_width = src.width + len_dalta_width * 2; int des_height = src.height + len_dalta_height * 2; return new Rectangle(new Dimension(des_width, des_height)); } public static int getRotateAngleForPhoto(File file) { int angle = 0; Metadata metadata; try { metadata = ImageMetadataReader.readMetadata(file); Directory directory = metadata.getFirstDirectoryOfType(ExifDirectoryBase.class); if (directory.containsTag(ExifDirectoryBase.TAG_ORIENTATION)) { // Exif資訊中方向 int orientation = directory.getInt(ExifDirectoryBase.TAG_ORIENTATION); // 原圖片的方向資訊 if (6 == orientation) { //6旋轉90 angle = 90; } else if (3 == orientation) { //3旋轉180 angle = 180; } else if (8 == orientation) { //8旋轉90 angle = 270; } } } catch (Exception e) { e.printStackTrace(); } return angle; } }