Skip to content

Commit

Permalink
webp to png conversion added, #249
Browse files Browse the repository at this point in the history
  • Loading branch information
Intelligent2013 committed Jun 8, 2024
1 parent 5a3d9d8 commit 3f97c5b
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SHELL ?= /bin/bash
endif

#JAR_VERSION := $(shell mvn -q -Dexec.executable="echo" -Dexec.args='$${project.version}' --non-recursive exec:exec -DforceStdout)
JAR_VERSION := 1.90
JAR_VERSION := 1.91
JAR_FILE := mn2pdf-$(JAR_VERSION).jar

all: target/$(JAR_FILE)
Expand Down
10 changes: 5 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ You will need the Java Development Kit (JDK) version 8, Update 241 (8u241) or hi

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.90.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.91.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
----

e.g.

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.90.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.91.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
----

=== PDF encryption features
Expand Down Expand Up @@ -100,7 +100,7 @@ Update version in `pom.xml`, e.g.:
----
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.90</version>
<version>1.91</version>
<name>Metanorma XML to PDF converter</name>
----

Expand All @@ -111,8 +111,8 @@ Tag the same version in Git:

[source,xml]
----
git tag v1.90
git push origin v1.90
git tag v1.91
git push origin v1.91
----

Then the corresponding GitHub release will be automatically created at:
Expand Down
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.90</version>
<version>1.91</version>
<name>Metanorma XML to PDF converter</name>
<packaging>jar</packaging>
<url>https://www.metanorma.org</url>
Expand Down Expand Up @@ -272,5 +272,10 @@
<artifactId>cssparser</artifactId>
<version>0.9.29</version>
</dependency>
<dependency>
<groupId>org.sejda.imageio</groupId>
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
</dependencies>
</project>
14 changes: 9 additions & 5 deletions src/main/java/org/metanorma/fop/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ 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 {
Expand Down Expand Up @@ -389,7 +390,8 @@ public static String getImageScale(String img, String width_effective, String he

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) {
Expand Down Expand Up @@ -417,14 +419,16 @@ private static int getDPI(ImageInputStream imageInputStream) {
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
147 changes: 147 additions & 0 deletions src/main/java/org/metanorma/fop/utils/ImageUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
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;

/**
*
* @author Alexander Dyuzhev
*/
public class ImageUtils {
protected static final Logger logger = Logger.getLogger(LoggerHelper.LOGGER_NAME);

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));

}
} 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) {
}
}

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 static String convertWebPtoPNG(String img) {
try {
BufferedImage bufferedImage;
if (!img.startsWith("data:")) {
File file = new File(img);
String filenameOut = img.substring(0, img.lastIndexOf(".")) + ".png";
File fileOut = new File(filenameOut);
bufferedImage = ImageIO.read(file);
ImageIO.write(bufferedImage, "png", fileOut);
return filenameOut;
} 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);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
byte[] imgPNGbytes = baos.toByteArray();
String imgPNGbase64 = Base64.getEncoder().encodeToString(imgPNGbytes);
return "data:image/png;base64," + imgPNGbase64;
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Can''t read the image: {0}", ex.toString());
}
return img;
}
}
63 changes: 63 additions & 0 deletions src/test/java/org/metanorma/fop/ImageUtilTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.metanorma.fop;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.EnvironmentVariables;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
import org.junit.contrib.java.lang.system.SystemErrRule;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.rules.TestName;
import org.metanorma.fop.utils.ImageUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;

import static org.junit.Assert.assertTrue;

public class ImageUtilTests {

@Rule
public final ExpectedSystemExit exitRule = ExpectedSystemExit.none();

@Rule
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();

@Rule
public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

@Rule
public final EnvironmentVariables envVarRule = new EnvironmentVariables();

@Rule public TestName name = new TestName();

@Test
public void testImageWebPtoPNG() throws IOException {
System.out.println(name.getMethodName());
ClassLoader classLoader = getClass().getClassLoader();
String imageFilename = new File(classLoader.getResource("sample.webp").getFile()).getAbsolutePath();

String imagepathPNG = ImageUtils.convertWebPtoPNG(imageFilename);
assertTrue(Files.exists(Paths.get(imagepathPNG)));

String imageScale = Util.getImageScale(imagepathPNG, "100", "200");
assertTrue(imageScale.equals("37"));
}

@Test
public void testImageBase64WebPtoPNG() throws IOException {
System.out.println(name.getMethodName());
ClassLoader classLoader = getClass().getClassLoader();
String imageFilename = classLoader.getResource("sample.webp").getFile();
byte[] imageContent = Files.readAllBytes(new File(imageFilename).toPath());
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");
assertTrue(imageScale.equals("37"));
}

}
Binary file added src/test/resources/sample.webp
Binary file not shown.

0 comments on commit 3f97c5b

Please sign in to comment.