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
---
juick-server-web/build.gradle | 1 +
.../java/com/juick/server/util/ImageUtils.java | 77 ++++++++++++++++++++--
2 files changed, 74 insertions(+), 4 deletions(-)
(limited to 'juick-server-web')
diff --git a/juick-server-web/build.gradle b/juick-server-web/build.gradle
index 92f017e4..3ca262bd 100644
--- a/juick-server-web/build.gradle
+++ b/juick-server-web/build.gradle
@@ -41,6 +41,7 @@ dependencies {
compile "rocks.xmpp:xmpp-extensions-client:0.7.4"
compile 'org.imgscalr:imgscalr-lib:4.2'
+ compile "org.apache.commons:commons-imaging:1.0-SNAPSHOT"
providedCompile "javax.servlet:javax.servlet-api:3.1.0"
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