From c92807772b49dc8c235b22ae67112446b38fb2f5 Mon Sep 17 00:00:00 2001 From: KillyMXI Date: Sat, 1 Jul 2017 20:45:54 +0300 Subject: create preview images with respect to EXIF Orientation tag --- .../java/com/juick/server/util/ImageUtils.java | 77 ++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) (limited to 'juick-server-web/src/main') diff --git a/juick-server-web/src/main/java/com/juick/server/util/ImageUtils.java b/juick-server-web/src/main/java/com/juick/server/util/ImageUtils.java index 61677750..00fe21ef 100644 --- a/juick-server-web/src/main/java/com/juick/server/util/ImageUtils.java +++ b/juick-server-web/src/main/java/com/juick/server/util/ImageUtils.java @@ -2,11 +2,19 @@ package com.juick.server.util; import org.apache.commons.io.FilenameUtils; +import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.Imaging; +import org.apache.commons.imaging.common.ImageMetadata; +import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata; +import org.apache.commons.imaging.formats.tiff.TiffField; +import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; import org.imgscalr.Scalr; +import org.imgscalr.Scalr.Rotation; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -14,12 +22,73 @@ import java.nio.file.StandardCopyOption; public class ImageUtils { +/** + * Returns BufferedImage, same as ImageIO.read() does. + * + *

JPEG images with EXIF metadata are rotated according to Orientation tag. + * + * @param imageFile a File to read from. + */ + private static BufferedImage readImageWithOrientation(File imageFile) + throws IOException { + + BufferedImage image = ImageIO.read(imageFile); + if (!FilenameUtils.getExtension(imageFile.getName()).equals("jpg")) { + return image; + } + + try { + ImageMetadata metadata = Imaging.getMetadata(imageFile); + + if (metadata instanceof JpegImageMetadata) { + JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; + TiffField orientationField = jpegMetadata.findEXIFValue(TiffTagConstants.TIFF_TAG_ORIENTATION); + + if (orientationField != null) { + int orientation = orientationField.getIntValue(); + switch (orientation) { + case TiffTagConstants.ORIENTATION_VALUE_ROTATE_90_CW: + image = Scalr.rotate(image, Rotation.CW_90); + break; + case TiffTagConstants.ORIENTATION_VALUE_ROTATE_180: + image = Scalr.rotate(image, Rotation.CW_180); + break; + case TiffTagConstants.ORIENTATION_VALUE_ROTATE_270_CW: + image = Scalr.rotate(image, Rotation.CW_270); + break; + case TiffTagConstants.ORIENTATION_VALUE_MIRROR_HORIZONTAL: + image = Scalr.rotate(image, Rotation.FLIP_HORZ); + break; + case TiffTagConstants.ORIENTATION_VALUE_MIRROR_VERTICAL: + image = Scalr.rotate(image, Rotation.FLIP_VERT); + break; + case TiffTagConstants.ORIENTATION_VALUE_MIRROR_HORIZONTAL_AND_ROTATE_90_CW: + image = Scalr.rotate(Scalr.rotate(image, Rotation.FLIP_HORZ), Rotation.CW_90); + break; + case TiffTagConstants.ORIENTATION_VALUE_MIRROR_HORIZONTAL_AND_ROTATE_270_CW: + image = Scalr.rotate(Scalr.rotate(image, Rotation.FLIP_HORZ), Rotation.CW_270); + break; + case TiffTagConstants.ORIENTATION_VALUE_HORIZONTAL_NORMAL: + default: + // do nothing + break; + } + } + } + } catch (ImageReadException e) { + // failed to read metadata. + // nothing to do here, return image as is. + } + + return image; + } + /** * Move attached image from temp folder to image folder. * Create preview images in corresponding folders. * - * @param tempFilename Name of the image file in temp folder. - * @param outputFilename Name that will be used in in image folder. + * @param tempFilename Name of the image file in the temp folder. + * @param outputFilename Name that will be used in the image folder. * @param tmpDir Path string for the temp folder. * @param imgDir Path string for the image folder. */ @@ -29,7 +98,7 @@ public class ImageUtils { Path outputImagePath = Paths.get(imgDir, "p", outputFilename); Files.move(Paths.get(tmpDir, tempFilename), outputImagePath); - BufferedImage originalImage = ImageIO.read(outputImagePath.toFile()); + BufferedImage originalImage = readImageWithOrientation(outputImagePath.toFile()); int width = originalImage.getWidth(); int height = originalImage.getHeight(); @@ -45,7 +114,7 @@ public class ImageUtils { /** * Save new avatar in all required sizes. * - * @param tempFilename Name of the image file in temp folder. + * @param tempFilename Name of the image file in the temp folder. * @param uid User id that is used to build image file names. * @param tmpDir Path string for the temp folder. * @param imgDir Path string for the image folder. -- cgit v1.2.3