diff --git a/classifai-core/pom.xml b/classifai-core/pom.xml
index 977fdb690..e597bf33e 100644
--- a/classifai-core/pom.xml
+++ b/classifai-core/pom.xml
@@ -104,6 +104,10 @@
com.github.jai-imageio
jai-imageio-jpeg2000
+
+ com.drewnoakes
+ metadata-extractor
+
diff --git a/classifai-core/src/main/java/ai/classifai/util/data/ImageHandler.java b/classifai-core/src/main/java/ai/classifai/util/data/ImageHandler.java
index c996adab4..a1fd8fda5 100644
--- a/classifai-core/src/main/java/ai/classifai/util/data/ImageHandler.java
+++ b/classifai-core/src/main/java/ai/classifai/util/data/ImageHandler.java
@@ -26,6 +26,10 @@
import ai.classifai.util.ParamConfig;
import ai.classifai.util.ProjectHandler;
import ai.classifai.util.type.AnnotationType;
+import com.drew.imaging.jpeg.JpegMetadataReader;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifIFD0Directory;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@@ -100,6 +104,66 @@ public static boolean isImageReadable(String imagePath)
}
+ private static int getExifOrientation(File file){
+ try
+ {
+ Metadata metadata = JpegMetadataReader.readMetadata(file);
+ Directory dir= metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+
+ return dir.getInt(274);
+ }
+ catch(Exception e)
+ {
+ return 0;
+ }
+ }
+
+ private static BufferedImage rotate(BufferedImage image, double angle){
+
+ double sin = Math.abs(Math.sin(angle));
+ double cos = Math.abs(Math.cos(angle));
+
+ int w = image.getWidth();
+ int h = image.getHeight();
+
+ int newW = (int) Math.floor(w * cos + h * sin);
+ int newH = (int) Math.floor(h * cos + w * sin);
+
+ int type = image.getType();
+ BufferedImage result = new BufferedImage(newW, newH, type);
+
+ Graphics2D g = result.createGraphics();
+
+ g.translate((newW - w) / 2, (newH - h) / 2);
+ g.rotate(angle,((double)w) / 2, ((double)h) / 2);
+ g.drawRenderedImage(image, null);
+
+ return result;
+ }
+
+ private static BufferedImage rotateWithOrientation(BufferedImage img, int orientation){
+ double angle = 0;
+ if (orientation == 8) angle = -Math.PI/2;
+ else if (orientation == 3) angle = Math.PI;
+ else if (orientation == 6) angle = Math.PI/2;
+
+ return rotate(img,angle);
+ }
+
+ private static int getHeight(BufferedImage img, int orientation){
+ if (orientation == 8 || orientation == 6){
+ return img.getWidth();
+ }
+ return img.getHeight();
+ }
+
+ private static int getWidth(BufferedImage img, int orientation){
+ if (orientation == 8 || orientation == 6){
+ return img.getHeight();
+ }
+ return img.getWidth();
+ }
+
public static Map getThumbNail(String imageAbsPath)
{
@@ -108,9 +172,13 @@ public static Map getThumbNail(String imageAbsPath)
File file = new File(imageAbsPath);
BufferedImage img = ImageIO.read(file);
+ int orientation = getExifOrientation(file);
+
+ Integer oriHeight = getHeight(img, orientation);
+ Integer oriWidth = getWidth(img, orientation);
- Integer oriHeight = img.getHeight();
- Integer oriWidth = img.getWidth();
+ //rotate for thumbnail generation
+ img = rotateWithOrientation(img, orientation);
int type = img.getColorModel().getColorSpace().getType();
boolean grayscale = (type == ColorSpace.TYPE_GRAY || type == ColorSpace.CS_GRAY);
diff --git a/pom.xml b/pom.xml
index ecc178a0f..06f65ba87 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,7 @@
3.8.1
3.2.4
3.8.1
+ 2.15.0
14
14
1.1.0
@@ -212,6 +213,11 @@
jai-imageio-jpeg2000
${jai.imageio.version}
+
+ com.drewnoakes
+ metadata-extractor
+ ${metadata.extractor.version}
+