Skip to content

Commit

Permalink
ImageUtils refactored, metanorma/metanorma-jis#226
Browse files Browse the repository at this point in the history
  • Loading branch information
Intelligent2013 committed Nov 13, 2024
1 parent 6227874 commit 228b019
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 189 deletions.
98 changes: 0 additions & 98 deletions src/main/java/org/metanorma/fop/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<ImageReader> 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 {
Expand Down
125 changes: 125 additions & 0 deletions src/main/java/org/metanorma/fop/utils/ImageData.java
Original file line number Diff line number Diff line change
@@ -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<ImageReader> 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;
}
}
100 changes: 11 additions & 89 deletions src/main/java/org/metanorma/fop/utils/ImageUtils.java
Original file line number Diff line number Diff line change
@@ -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;

/**
*
Expand All @@ -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<ImageReader> 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 {
Expand Down
7 changes: 5 additions & 2 deletions src/test/java/org/metanorma/fop/ImageUtilTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"));
}

Expand Down

0 comments on commit 228b019

Please sign in to comment.