From 82876015357ee4c536bdca954025351beb7e3ed9 Mon Sep 17 00:00:00 2001 From: Boubaker Khanfir Date: Fri, 23 Aug 2024 08:52:07 +0100 Subject: [PATCH] fix: Fix preserving Image EXIF Orientation Metadata after scaling - MEED-2471 - Meeds-io/meeds#1126 (#633) Prior to this change, when attaching a JPEG image took by Camera in landscape and then attach it in an activity, then the image preview orientation will change. This change will preserve Image metadata after scaling in order to fix the lack of EXIF information in resulted Resized Image. (cherry picked from commit 7d9d259f693a6908f04eba736375c7b3cf6860d7) --- .../thumbnail/ImageResizeServiceImpl.java | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/commons-component-common/src/main/java/org/exoplatform/services/thumbnail/ImageResizeServiceImpl.java b/commons-component-common/src/main/java/org/exoplatform/services/thumbnail/ImageResizeServiceImpl.java index 900183f7e4..99fd46a0bd 100644 --- a/commons-component-common/src/main/java/org/exoplatform/services/thumbnail/ImageResizeServiceImpl.java +++ b/commons-component-common/src/main/java/org/exoplatform/services/thumbnail/ImageResizeServiceImpl.java @@ -15,15 +15,23 @@ */ package org.exoplatform.services.thumbnail; -import org.exoplatform.services.log.ExoLogger; -import org.exoplatform.services.log.Log; -import org.imgscalr.Scalr; - -import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Iterator; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; + +import org.imgscalr.Scalr; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; public class ImageResizeServiceImpl implements ImageResizeService { @@ -49,7 +57,7 @@ public byte[] scaleImage(byte[] image, int width, int height, boolean fitExact, return image; } - + ImageReader imageReader = getImageReader(image); if (width == 0) { bufferedImage = Scalr.resize(bufferedImage, resizeMethod, Scalr.Mode.FIT_TO_HEIGHT, width, height, Scalr.OP_ANTIALIAS); } else if (height == 0) { @@ -67,15 +75,26 @@ public byte[] scaleImage(byte[] image, int width, int height, boolean fitExact, bufferedImage = Scalr.resize(bufferedImage, resizeMethod, fitMode, width, height, Scalr.OP_ANTIALIAS); } - byte[] response = toByteArray(bufferedImage); - if (response.length > image.length) { - //if the original image is smaller in weight from the resized image, we must keep the original image + + byte[] response = toByteArray(bufferedImage, imageReader); + + if (!fitExact && response.length > image.length) { + // if the original image is smaller in weight from the resized image, we + // must keep the original image return image; } else { return response; } } + private ImageReader getImageReader(byte[] bytes) throws IOException { + ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(bytes)); + Iterator readers = ImageIO.getImageReaders(imageInputStream); + ImageReader reader = readers.next(); + reader.setInput(imageInputStream); + return reader; + } + private BufferedImage toBufferedImage(byte[] imageBytes) { try { ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes); @@ -86,9 +105,14 @@ private BufferedImage toBufferedImage(byte[] imageBytes) { } } - private byte[] toByteArray(BufferedImage bufferedImage) throws IOException { + private byte[] toByteArray(BufferedImage targetBufferedImage, ImageReader sourceImageReader) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ImageIO.write(bufferedImage, "png", byteArrayOutputStream); + ImageWriter writer = ImageIO.getImageWriter(sourceImageReader); + writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream)); + + IIOMetadata metadata = sourceImageReader.getImageMetadata(0); + writer.write(new IIOImage(targetBufferedImage, null, metadata)); + writer.dispose(); return byteArrayOutputStream.toByteArray(); }