From a3d6a34cd6fbf2d4e82ddafc2df065830e729e18 Mon Sep 17 00:00:00 2001 From: leebj Date: Thu, 16 Jan 2025 08:56:13 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EC=B6=95=EC=86=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 11 +++ .../java/cokr/xit/applib/AppCmmnUtil.java | 83 +++++++++++++++++++ src/main/java/cokr/xit/applib/Pstn.java | 20 +++++ .../java/cokr/xit/applib/PstnAndSize.java | 75 +++++++++++++++++ src/main/java/cokr/xit/applib/Size.java | 56 +++++++++++++ 5 files changed, 245 insertions(+) create mode 100644 src/main/java/cokr/xit/applib/Pstn.java create mode 100644 src/main/java/cokr/xit/applib/PstnAndSize.java create mode 100644 src/main/java/cokr/xit/applib/Size.java diff --git a/pom.xml b/pom.xml index 71f739a..08251fb 100644 --- a/pom.xml +++ b/pom.xml @@ -126,6 +126,17 @@ provided + + org.apache.commons + commons-imaging + 1.0.0-alpha5 + + + com.drewnoakes + metadata-extractor + 2.19.0 + + diff --git a/src/main/java/cokr/xit/applib/AppCmmnUtil.java b/src/main/java/cokr/xit/applib/AppCmmnUtil.java index 47946bd..61de35f 100644 --- a/src/main/java/cokr/xit/applib/AppCmmnUtil.java +++ b/src/main/java/cokr/xit/applib/AppCmmnUtil.java @@ -1,10 +1,23 @@ package cokr.xit.applib; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; +import org.apache.commons.io.FilenameUtils; + +import com.drew.imaging.ImageMetadataReader; +import com.drew.metadata.Metadata; +import com.drew.metadata.exif.ExifIFD0Directory; + public class AppCmmnUtil { /** @@ -185,4 +198,74 @@ public class AppCmmnUtil { } } + static int MIN_WH = 480; + public static byte[] resizeImage(String path) throws Exception { + File file = new File(path); + BufferedImage originalImage = ImageIO.read(file); + int orientation = 0; + + Metadata metadata = ImageMetadataReader.readMetadata(file); + if(metadata != null) { + ExifIFD0Directory dir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); + if(dir != null) { + orientation = dir.getInt(ExifIFD0Directory.TAG_ORIENTATION); + if(orientation == TiffTagConstants.ORIENTATION_VALUE_ROTATE_90_CW) { + originalImage = getRotateImage(originalImage,90); + } else if(orientation == TiffTagConstants.ORIENTATION_VALUE_ROTATE_180) { + originalImage = getRotateImage(originalImage,180); + } else if(orientation == TiffTagConstants.ORIENTATION_VALUE_ROTATE_270_CW) { + originalImage = getRotateImage(originalImage,270); + } + } + } + + int orig_height = originalImage.getHeight(); + int orig_width = originalImage.getWidth(); + + String ext = FilenameUtils.getExtension(path); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + if(orig_height <= MIN_WH || orig_width <= MIN_WH) { + ImageIO.write(originalImage, ext, baos); + byte[] bytes = baos.toByteArray(); + return bytes; + } + + Size size = new Size(orig_width,orig_height); + int[] re = size.reduceUntil(MIN_WH, true).to2Int(); + + int re_width = re[0]; + int re_height = re[1]; + + BufferedImage outputImage = resizeImage(originalImage, re_width, re_height); + ImageIO.write(outputImage, ext, baos); + byte[] bytes = baos.toByteArray(); + return bytes; + } + + public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) { + Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT); + BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage. TYPE_INT_RGB); + outputImage.getGraphics().drawImage(resultingImage, 0, 0, null); + return outputImage; + } + + public static BufferedImage getRotateImage(BufferedImage image, int rotate){ + BufferedImage newImage = null; + if(180 == rotate) { + newImage = new BufferedImage(image.getWidth(),image.getHeight(), image.getType()); + } else { + newImage = new BufferedImage(image.getHeight(),image.getWidth(), image.getType()); + } + + Graphics2D graphics = (Graphics2D) newImage.getGraphics(); + graphics.rotate(Math.toRadians(rotate), newImage.getWidth() / 2, newImage.getHeight() / 2); + if(180 != rotate) { + graphics.translate((newImage.getWidth() - image.getWidth()) / 2, (newImage.getHeight() - image.getHeight()) / 2); + } + graphics.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); + + return newImage; + } + } diff --git a/src/main/java/cokr/xit/applib/Pstn.java b/src/main/java/cokr/xit/applib/Pstn.java new file mode 100644 index 0000000..1d3cbc3 --- /dev/null +++ b/src/main/java/cokr/xit/applib/Pstn.java @@ -0,0 +1,20 @@ +package cokr.xit.applib; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Pstn { + public Pstn(float left, float top){ + this.left = left; + this.top = top; + } + + private float left; + private float top; + + public float[] to2Float() { + return new float[] { this.left, this.top }; + } +} diff --git a/src/main/java/cokr/xit/applib/PstnAndSize.java b/src/main/java/cokr/xit/applib/PstnAndSize.java new file mode 100644 index 0000000..8390897 --- /dev/null +++ b/src/main/java/cokr/xit/applib/PstnAndSize.java @@ -0,0 +1,75 @@ +package cokr.xit.applib; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PstnAndSize { + public PstnAndSize(float left, float top, float width, float height){ + this.left = left; + this.top = top; + this.width = width; + this.height = height; + } + + public PstnAndSize(Pstn pstn, Size size){ + this.left = pstn.getLeft(); + this.top = pstn.getTop(); + this.width = size.getWidth(); + this.height = size.getHeight(); + } + + public PstnAndSize(Pstn pstn, float width, float height){ + this.left = pstn.getLeft(); + this.top = pstn.getTop(); + this.width = width; + this.height = height; + } + + public PstnAndSize(float left, float top, Size size){ + this.left = left; + this.top = top; + this.width = size.getWidth(); + this.height = size.getHeight(); + } + + private float left; + private float top; + private float width; + private float height; + + public Pstn getPstn() { + return new Pstn(this.left, this.top); + } + public Size getSize() { + return new Size(this.width, this.height); + } + + public float[] to4Float() { + return new float[] { this.left, this.top, this.width, this.height }; + } + + public PstnAndSize x2Width() { + this.width = this.width * 2.0f; + return this; + } + public PstnAndSize x2Height() { + this.height = this.height * 2.0f; + return this; + } + + public PstnAndSize transXY(float transX, float transY) { + this.left = this.left * transX; + this.top = this.top * transY; + this.width = this.width * transX; + this.height = this.height * transY; + return this; + } + + public PstnAndSize addPstn(Pstn pstn) { + this.left = this.left + pstn.getLeft(); + this.top = this.top + pstn.getTop(); + return this; + } +} diff --git a/src/main/java/cokr/xit/applib/Size.java b/src/main/java/cokr/xit/applib/Size.java new file mode 100644 index 0000000..60c9cfd --- /dev/null +++ b/src/main/java/cokr/xit/applib/Size.java @@ -0,0 +1,56 @@ +package cokr.xit.applib; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Size { + public Size(float width, float height){ + this.width = width; + this.height = height; + } + + private float width; + private float height; + + public float[] to2Float() { + return new float[] { this.width, this.height }; + } + + public int[] to2Int() { + return new int[] { (int)this.width, (int)this.height }; + } + + /** + * 지정한 수치가 될 때까지 정비례로 크기를 축소한다. + * @param until 축소할 축(x 또는 y)의 길이 지정 + * @param minMax 축소할 대상 축의 선택방법 지정(가장 길이가 작은 축 또는 가장 길이가 긴 축) + * @return Size + */ + public Size reduceUntil(int until, boolean minMax) { + + float minAxisValue; + float maxAxisValue; + if(this.width <= this.height) { + minAxisValue = this.width; + maxAxisValue = this.height; + } else { + minAxisValue = this.height; + maxAxisValue = this.width; + } + + float divisor; //피제수 + if(minMax) { + divisor = (minAxisValue / until); + } else { + divisor = (maxAxisValue / until); + } + + this.width = this.width / divisor; + this.height = this.height / divisor; + + return this; + } + +}