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} +