From 228b0196b6f324c7c5ae524b2f1cc8415b2bb2f8 Mon Sep 17 00:00:00 2001 From: Alexander Dyuzhev Date: Wed, 13 Nov 2024 19:52:09 +0300 Subject: [PATCH] ImageUtils refactored, metanorma/metanorma-jis#226 --- src/main/java/org/metanorma/fop/Util.java | 98 -------------- .../org/metanorma/fop/utils/ImageData.java | 125 ++++++++++++++++++ .../org/metanorma/fop/utils/ImageUtils.java | 100 ++------------ .../org/metanorma/fop/ImageUtilTests.java | 7 +- 4 files changed, 141 insertions(+), 189 deletions(-) create mode 100644 src/main/java/org/metanorma/fop/utils/ImageData.java diff --git a/src/main/java/org/metanorma/fop/Util.java b/src/main/java/org/metanorma/fop/Util.java index da7b8d9..63dd5ff 100644 --- a/src/main/java/org/metanorma/fop/Util.java +++ b/src/main/java/org/metanorma/fop/Util.java @@ -331,104 +331,6 @@ public static InputStream getStreamFromResources(ClassLoader classLoader, String return stream; } - // TODO: remove in the next release (moved into the ImageUtils class) - public static String getImageScale(String img, String width_effective, String height_effective) { - - try { - BufferedImage bufferedImage; - ImageInputStream imageInputStream; - if (!img.startsWith("data:")) { - File file = new File(img); - bufferedImage = ImageIO.read(file); - imageInputStream = ImageIO.createImageInputStream(file); - } else { - String base64String = img.substring(img.indexOf("base64,") + 7); - Decoder base64Decoder = Base64.getDecoder(); - byte[] fileContent = base64Decoder.decode(base64String); - ByteArrayInputStream bais = new ByteArrayInputStream(fileContent); - bufferedImage = ImageIO.read(bais); - - ByteArrayInputStream baisDPI = new ByteArrayInputStream(fileContent); - imageInputStream = ImageIO.createImageInputStream(baisDPI); - } - if (bufferedImage != null) { - int width_px = bufferedImage.getWidth(); - int height_px = bufferedImage.getHeight(); - - int image_dpi = getDPI(imageInputStream); - - double width_mm = Double.valueOf(width_px) / image_dpi * 25.4; - double height_mm = Double.valueOf(height_px) / image_dpi * 25.4; - - //double width_effective_px = Double.valueOf(width_effective) / 25.4 * image_dpi; - //double height_effective_px = Double.valueOf(height_effective) / 25.4 * image_dpi; - double width_effective_mm = Double.valueOf(width_effective); - double height_effective_mm = Double.valueOf(height_effective); - - - double scale_x = 1.0; - if (width_mm > width_effective_mm) { - scale_x = width_effective_mm / width_mm; - } - - double scale_y = 1.0; - if (height_mm * scale_x > height_effective_mm) { - scale_y = height_effective_mm / (height_mm * scale_x); - } - - double scale = scale_x; - if (scale_y != 1.0) { - scale = scale_x * scale_y; - } - - return String.valueOf(Math.round(scale * 100)); - - } - } catch (Exception ex) { - logger.log(Level.SEVERE, "Can''t read DPI from image: {0}", ex.toString()); - } - - return "100"; - } - - // TODO: remove in the next release (moved into the ImageUtils class) - private static int getDPI(ImageInputStream imageInputStream) { - int default_DPI = 96; - if (imageInputStream != null) { - try { - Iterator readers = ImageIO.getImageReaders(imageInputStream); - if (readers.hasNext()) { - ImageReader reader = readers.next(); - reader.setInput(imageInputStream); - - IIOMetadata metadata = reader.getImageMetadata(0); - IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); - IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0); - float pixelSizeMM = getPixelSizeMM(dimension, "HorizontalPixelSize"); - if (pixelSizeMM == -1.0f) { // try get verrical pixel size - pixelSizeMM = getPixelSizeMM(dimension, "VerticalPixelSize"); - } - if (pixelSizeMM == -1.0f) return default_DPI; - float dpi = (float) (25.4f / pixelSizeMM); - return Math.round(dpi); - } - } catch (Exception ex) { - } - } - - logger.log(Level.SEVERE, "Could not read image DPI, use default value {0} DPI", default_DPI); - return default_DPI; //default DPI - } - - - // TODO: remove in the next release (moved into the ImageUtils class) - private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) { - NodeList pixelSizes = dimension.getElementsByTagName(elementName); - IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null; - return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1; - } - - public static int getCoverPagesCount (File fXSL) { int countpages = 0; try { diff --git a/src/main/java/org/metanorma/fop/utils/ImageData.java b/src/main/java/org/metanorma/fop/utils/ImageData.java new file mode 100644 index 0000000..90e140e --- /dev/null +++ b/src/main/java/org/metanorma/fop/utils/ImageData.java @@ -0,0 +1,125 @@ +package org.metanorma.fop.utils; + +import org.metanorma.utils.LoggerHelper; +import org.w3c.dom.NodeList; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataFormatImpl; +import javax.imageio.metadata.IIOMetadataNode; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.util.Base64; +import java.util.Iterator; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ImageData { + + protected static final Logger logger = Logger.getLogger(LoggerHelper.LOGGER_NAME); + + private BufferedImage bufferedImage; + private ImageInputStream imageInputStream; + + private double scale = 1; + private double width_mm; + private double height_mm; + + ImageData(String img, String width_effective, String height_effective) throws IOException { + if (!img.startsWith("data:")) { + File file = new File(img); + bufferedImage = ImageIO.read(file); + imageInputStream = ImageIO.createImageInputStream(file); + } else { + String base64String = img.substring(img.indexOf("base64,") + 7); + Base64.Decoder base64Decoder = Base64.getDecoder(); + byte[] fileContent = base64Decoder.decode(base64String); + ByteArrayInputStream bais = new ByteArrayInputStream(fileContent); + bufferedImage = ImageIO.read(bais); + + ByteArrayInputStream baisDPI = new ByteArrayInputStream(fileContent); + imageInputStream = ImageIO.createImageInputStream(baisDPI); + } + + if (bufferedImage != null) { + int width_px = bufferedImage.getWidth(); + int height_px = bufferedImage.getHeight(); + + int image_dpi = getDPI(imageInputStream); + + this.width_mm = Double.valueOf(width_px) / image_dpi * 25.4; + this.height_mm = Double.valueOf(height_px) / image_dpi * 25.4; + + //double width_effective_px = Double.valueOf(width_effective) / 25.4 * image_dpi; + //double height_effective_px = Double.valueOf(height_effective) / 25.4 * image_dpi; + double width_effective_mm = Double.valueOf(width_effective); + double height_effective_mm = Double.valueOf(height_effective); + + double scale_x = 1.0; + if (width_mm > width_effective_mm) { + scale_x = width_effective_mm / width_mm; + } + + double scale_y = 1.0; + if (height_mm * scale_x > height_effective_mm) { + scale_y = height_effective_mm / (height_mm * scale_x); + } + + this.scale = scale_x; + if (scale_y != 1.0) { + this.scale = scale_x * scale_y; + } + + //this.scale = Math.round(scale * 100); + + } + + } + + private static int getDPI(ImageInputStream imageInputStream) { + int default_DPI = 96; + if (imageInputStream != null) { + try { + Iterator readers = ImageIO.getImageReaders(imageInputStream); + if (readers.hasNext()) { + ImageReader reader = readers.next(); + reader.setInput(imageInputStream); + + IIOMetadata metadata = reader.getImageMetadata(0); + IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); + IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0); + float pixelSizeMM = getPixelSizeMM(dimension, "HorizontalPixelSize"); + if (pixelSizeMM == -1.0f) { // try get verrical pixel size + pixelSizeMM = getPixelSizeMM(dimension, "VerticalPixelSize"); + } + if (pixelSizeMM == -1.0f) return default_DPI; + float dpi = (float) (25.4f / pixelSizeMM); + return Math.round(dpi); + } + } catch (Exception ex) { + } + } + + logger.log(Level.SEVERE, "Could not read image DPI, use default value {0} DPI", default_DPI); + return default_DPI; //default DPI + } + + private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) { + NodeList pixelSizes = dimension.getElementsByTagName(elementName); + IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null; + return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1; + } + + + public long getImageScale() { + return Math.round(scale * 100); + } + + public double getImageWidth() { + return width_mm * scale; + } +} diff --git a/src/main/java/org/metanorma/fop/utils/ImageUtils.java b/src/main/java/org/metanorma/fop/utils/ImageUtils.java index 3234ed5..cb52787 100644 --- a/src/main/java/org/metanorma/fop/utils/ImageUtils.java +++ b/src/main/java/org/metanorma/fop/utils/ImageUtils.java @@ -1,22 +1,14 @@ package org.metanorma.fop.utils; -import org.metanorma.utils.LoggerHelper; -import org.w3c.dom.NodeList; - import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.stream.ImageInputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.Base64; -import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; +import org.metanorma.utils.LoggerHelper; /** * @@ -27,95 +19,25 @@ public class ImageUtils { public static String getImageScale(String img, String width_effective, String height_effective) { try { - BufferedImage bufferedImage; - ImageInputStream imageInputStream; - if (!img.startsWith("data:")) { - File file = new File(img); - bufferedImage = ImageIO.read(file); - imageInputStream = ImageIO.createImageInputStream(file); - } else { - String base64String = img.substring(img.indexOf("base64,") + 7); - Base64.Decoder base64Decoder = Base64.getDecoder(); - byte[] fileContent = base64Decoder.decode(base64String); - ByteArrayInputStream bais = new ByteArrayInputStream(fileContent); - bufferedImage = ImageIO.read(bais); - - ByteArrayInputStream baisDPI = new ByteArrayInputStream(fileContent); - imageInputStream = ImageIO.createImageInputStream(baisDPI); - } - if (bufferedImage != null) { - int width_px = bufferedImage.getWidth(); - int height_px = bufferedImage.getHeight(); - - int image_dpi = getDPI(imageInputStream); - - double width_mm = Double.valueOf(width_px) / image_dpi * 25.4; - double height_mm = Double.valueOf(height_px) / image_dpi * 25.4; - - //double width_effective_px = Double.valueOf(width_effective) / 25.4 * image_dpi; - //double height_effective_px = Double.valueOf(height_effective) / 25.4 * image_dpi; - double width_effective_mm = Double.valueOf(width_effective); - double height_effective_mm = Double.valueOf(height_effective); - - - double scale_x = 1.0; - if (width_mm > width_effective_mm) { - scale_x = width_effective_mm / width_mm; - } - - double scale_y = 1.0; - if (height_mm * scale_x > height_effective_mm) { - scale_y = height_effective_mm / (height_mm * scale_x); - } - - double scale = scale_x; - if (scale_y != 1.0) { - scale = scale_x * scale_y; - } - - return String.valueOf(Math.round(scale * 100)); - - } + ImageData imageData = new ImageData(img, width_effective, height_effective); + return String.valueOf(imageData.getImageScale()); } catch (Exception ex) { logger.log(Level.SEVERE, "Can''t read DPI from image: {0}", ex.toString()); } - return "100"; } - private static int getDPI(ImageInputStream imageInputStream) { - int default_DPI = 96; - if (imageInputStream != null) { - try { - Iterator readers = ImageIO.getImageReaders(imageInputStream); - if (readers.hasNext()) { - ImageReader reader = readers.next(); - reader.setInput(imageInputStream); - - IIOMetadata metadata = reader.getImageMetadata(0); - IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); - IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0); - float pixelSizeMM = getPixelSizeMM(dimension, "HorizontalPixelSize"); - if (pixelSizeMM == -1.0f) { // try get verrical pixel size - pixelSizeMM = getPixelSizeMM(dimension, "VerticalPixelSize"); - } - if (pixelSizeMM == -1.0f) return default_DPI; - float dpi = (float) (25.4f / pixelSizeMM); - return Math.round(dpi); - } - } catch (Exception ex) { - } + public static String getImageWidth(String img, String width_effective, String height_effective) { + try { + ImageData imageData = new ImageData(img, width_effective, height_effective); + return String.format("%.1f", imageData.getImageWidth()); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Can''t read DPI from image: {0}", ex.toString()); } - - logger.log(Level.SEVERE, "Could not read image DPI, use default value {0} DPI", default_DPI); - return default_DPI; //default DPI + return "100"; } - private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) { - NodeList pixelSizes = dimension.getElementsByTagName(elementName); - IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null; - return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1; - } + public static String convertWebPtoPNG(String img) { try { diff --git a/src/test/java/org/metanorma/fop/ImageUtilTests.java b/src/test/java/org/metanorma/fop/ImageUtilTests.java index 316179c..77af7f4 100644 --- a/src/test/java/org/metanorma/fop/ImageUtilTests.java +++ b/src/test/java/org/metanorma/fop/ImageUtilTests.java @@ -43,8 +43,11 @@ public void testImageWebPtoPNG() throws IOException { String imagepathPNG = ImageUtils.convertWebPtoPNG(imageFilename); assertTrue(Files.exists(Paths.get(imagepathPNG))); - String imageScale = Util.getImageScale(imagepathPNG, "100", "200"); + String imageScale = ImageUtils.getImageScale(imagepathPNG, "100", "200"); assertTrue(imageScale.equals("37")); + + String imageWidth = ImageUtils.getImageWidth(imagepathPNG, "10", "20"); + assertTrue(imageWidth.equals("10.0")); } @Test @@ -56,7 +59,7 @@ public void testImageBase64WebPtoPNG() throws IOException { String imageContentBase64 = "data:image/webp;base64," + Base64.getEncoder().encodeToString(imageContent); String imagePNGBase64 = ImageUtils.convertWebPtoPNG(imageContentBase64); assertTrue(imagePNGBase64.startsWith("data:image/png;base64,")); - String imageScale = Util.getImageScale(imagePNGBase64, "100", "200"); + String imageScale = ImageUtils.getImageScale(imagePNGBase64, "100", "200"); assertTrue(imageScale.equals("37")); }