Skip to content

Commit 4763ba6

Browse files
Merge pull request #252 from metanorma/feature/webp
webp to png conversion added, #249
2 parents 5a3d9d8 + 3f97c5b commit 4763ba6

File tree

7 files changed

+231
-12
lines changed

7 files changed

+231
-12
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ SHELL ?= /bin/bash
66
endif
77

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

1212
all: target/$(JAR_FILE)

README.adoc

+5-5
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ You will need the Java Development Kit (JDK) version 8, Update 241 (8u241) or hi
1717

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

2323
e.g.
2424

2525
[source,sh]
2626
----
27-
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
27+
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
2828
----
2929

3030
=== PDF encryption features
@@ -100,7 +100,7 @@ Update version in `pom.xml`, e.g.:
100100
----
101101
<groupId>org.metanorma.fop</groupId>
102102
<artifactId>mn2pdf</artifactId>
103-
<version>1.90</version>
103+
<version>1.91</version>
104104
<name>Metanorma XML to PDF converter</name>
105105
----
106106

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

112112
[source,xml]
113113
----
114-
git tag v1.90
115-
git push origin v1.90
114+
git tag v1.91
115+
git push origin v1.91
116116
----
117117

118118
Then the corresponding GitHub release will be automatically created at:

pom.xml

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>org.metanorma.fop</groupId>
77
<artifactId>mn2pdf</artifactId>
8-
<version>1.90</version>
8+
<version>1.91</version>
99
<name>Metanorma XML to PDF converter</name>
1010
<packaging>jar</packaging>
1111
<url>https://www.metanorma.org</url>
@@ -272,5 +272,10 @@
272272
<artifactId>cssparser</artifactId>
273273
<version>0.9.29</version>
274274
</dependency>
275+
<dependency>
276+
<groupId>org.sejda.imageio</groupId>
277+
<artifactId>webp-imageio</artifactId>
278+
<version>0.1.6</version>
279+
</dependency>
275280
</dependencies>
276281
</project>

src/main/java/org/metanorma/fop/Util.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ public static InputStream getStreamFromResources(ClassLoader classLoader, String
330330
}
331331
return stream;
332332
}
333-
333+
334+
// TODO: remove in the next release (moved into the ImageUtils class)
334335
public static String getImageScale(String img, String width_effective, String height_effective) {
335336

336337
try {
@@ -389,7 +390,8 @@ public static String getImageScale(String img, String width_effective, String he
389390

390391
return "100";
391392
}
392-
393+
394+
// TODO: remove in the next release (moved into the ImageUtils class)
393395
private static int getDPI(ImageInputStream imageInputStream) {
394396
int default_DPI = 96;
395397
if (imageInputStream != null) {
@@ -417,14 +419,16 @@ private static int getDPI(ImageInputStream imageInputStream) {
417419
logger.log(Level.SEVERE, "Could not read image DPI, use default value {0} DPI", default_DPI);
418420
return default_DPI; //default DPI
419421
}
420-
421-
422+
423+
424+
// TODO: remove in the next release (moved into the ImageUtils class)
422425
private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) {
423426
NodeList pixelSizes = dimension.getElementsByTagName(elementName);
424427
IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null;
425428
return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1;
426429
}
427-
430+
431+
428432
public static int getCoverPagesCount (File fXSL) {
429433
int countpages = 0;
430434
try {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package org.metanorma.fop.utils;
2+
3+
import org.metanorma.utils.LoggerHelper;
4+
import org.w3c.dom.NodeList;
5+
6+
import javax.imageio.ImageIO;
7+
import javax.imageio.ImageReader;
8+
import javax.imageio.metadata.IIOMetadata;
9+
import javax.imageio.metadata.IIOMetadataFormatImpl;
10+
import javax.imageio.metadata.IIOMetadataNode;
11+
import javax.imageio.stream.ImageInputStream;
12+
import java.awt.image.BufferedImage;
13+
import java.io.ByteArrayInputStream;
14+
import java.io.ByteArrayOutputStream;
15+
import java.io.File;
16+
import java.util.Base64;
17+
import java.util.Iterator;
18+
import java.util.logging.Level;
19+
import java.util.logging.Logger;
20+
21+
/**
22+
*
23+
* @author Alexander Dyuzhev
24+
*/
25+
public class ImageUtils {
26+
protected static final Logger logger = Logger.getLogger(LoggerHelper.LOGGER_NAME);
27+
28+
public static String getImageScale(String img, String width_effective, String height_effective) {
29+
try {
30+
BufferedImage bufferedImage;
31+
ImageInputStream imageInputStream;
32+
if (!img.startsWith("data:")) {
33+
File file = new File(img);
34+
bufferedImage = ImageIO.read(file);
35+
imageInputStream = ImageIO.createImageInputStream(file);
36+
} else {
37+
String base64String = img.substring(img.indexOf("base64,") + 7);
38+
Base64.Decoder base64Decoder = Base64.getDecoder();
39+
byte[] fileContent = base64Decoder.decode(base64String);
40+
ByteArrayInputStream bais = new ByteArrayInputStream(fileContent);
41+
bufferedImage = ImageIO.read(bais);
42+
43+
ByteArrayInputStream baisDPI = new ByteArrayInputStream(fileContent);
44+
imageInputStream = ImageIO.createImageInputStream(baisDPI);
45+
}
46+
if (bufferedImage != null) {
47+
int width_px = bufferedImage.getWidth();
48+
int height_px = bufferedImage.getHeight();
49+
50+
int image_dpi = getDPI(imageInputStream);
51+
52+
double width_mm = Double.valueOf(width_px) / image_dpi * 25.4;
53+
double height_mm = Double.valueOf(height_px) / image_dpi * 25.4;
54+
55+
//double width_effective_px = Double.valueOf(width_effective) / 25.4 * image_dpi;
56+
//double height_effective_px = Double.valueOf(height_effective) / 25.4 * image_dpi;
57+
double width_effective_mm = Double.valueOf(width_effective);
58+
double height_effective_mm = Double.valueOf(height_effective);
59+
60+
61+
double scale_x = 1.0;
62+
if (width_mm > width_effective_mm) {
63+
scale_x = width_effective_mm / width_mm;
64+
}
65+
66+
double scale_y = 1.0;
67+
if (height_mm * scale_x > height_effective_mm) {
68+
scale_y = height_effective_mm / (height_mm * scale_x);
69+
}
70+
71+
double scale = scale_x;
72+
if (scale_y != 1.0) {
73+
scale = scale_x * scale_y;
74+
}
75+
76+
return String.valueOf(Math.round(scale * 100));
77+
78+
}
79+
} catch (Exception ex) {
80+
logger.log(Level.SEVERE, "Can''t read DPI from image: {0}", ex.toString());
81+
}
82+
83+
return "100";
84+
}
85+
86+
private static int getDPI(ImageInputStream imageInputStream) {
87+
int default_DPI = 96;
88+
if (imageInputStream != null) {
89+
try {
90+
Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
91+
if (readers.hasNext()) {
92+
ImageReader reader = readers.next();
93+
reader.setInput(imageInputStream);
94+
95+
IIOMetadata metadata = reader.getImageMetadata(0);
96+
IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
97+
IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0);
98+
float pixelSizeMM = getPixelSizeMM(dimension, "HorizontalPixelSize");
99+
if (pixelSizeMM == -1.0f) { // try get verrical pixel size
100+
pixelSizeMM = getPixelSizeMM(dimension, "VerticalPixelSize");
101+
}
102+
if (pixelSizeMM == -1.0f) return default_DPI;
103+
float dpi = (float) (25.4f / pixelSizeMM);
104+
return Math.round(dpi);
105+
}
106+
} catch (Exception ex) {
107+
}
108+
}
109+
110+
logger.log(Level.SEVERE, "Could not read image DPI, use default value {0} DPI", default_DPI);
111+
return default_DPI; //default DPI
112+
}
113+
114+
private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) {
115+
NodeList pixelSizes = dimension.getElementsByTagName(elementName);
116+
IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null;
117+
return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1;
118+
}
119+
120+
public static String convertWebPtoPNG(String img) {
121+
try {
122+
BufferedImage bufferedImage;
123+
if (!img.startsWith("data:")) {
124+
File file = new File(img);
125+
String filenameOut = img.substring(0, img.lastIndexOf(".")) + ".png";
126+
File fileOut = new File(filenameOut);
127+
bufferedImage = ImageIO.read(file);
128+
ImageIO.write(bufferedImage, "png", fileOut);
129+
return filenameOut;
130+
} else {
131+
String base64String = img.substring(img.indexOf("base64,") + 7);
132+
Base64.Decoder base64Decoder = Base64.getDecoder();
133+
byte[] fileContent = base64Decoder.decode(base64String);
134+
ByteArrayInputStream bais = new ByteArrayInputStream(fileContent);
135+
bufferedImage = ImageIO.read(bais);
136+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
137+
ImageIO.write(bufferedImage, "png", baos);
138+
byte[] imgPNGbytes = baos.toByteArray();
139+
String imgPNGbase64 = Base64.getEncoder().encodeToString(imgPNGbytes);
140+
return "data:image/png;base64," + imgPNGbase64;
141+
}
142+
} catch (Exception ex) {
143+
logger.log(Level.SEVERE, "Can''t read the image: {0}", ex.toString());
144+
}
145+
return img;
146+
}
147+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.metanorma.fop;
2+
3+
import org.junit.Rule;
4+
import org.junit.Test;
5+
import org.junit.contrib.java.lang.system.EnvironmentVariables;
6+
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
7+
import org.junit.contrib.java.lang.system.SystemErrRule;
8+
import org.junit.contrib.java.lang.system.SystemOutRule;
9+
import org.junit.rules.TestName;
10+
import org.metanorma.fop.utils.ImageUtils;
11+
12+
import java.io.File;
13+
import java.io.IOException;
14+
import java.nio.file.Files;
15+
import java.nio.file.Path;
16+
import java.nio.file.Paths;
17+
import java.util.Base64;
18+
19+
import static org.junit.Assert.assertTrue;
20+
21+
public class ImageUtilTests {
22+
23+
@Rule
24+
public final ExpectedSystemExit exitRule = ExpectedSystemExit.none();
25+
26+
@Rule
27+
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
28+
29+
@Rule
30+
public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();
31+
32+
@Rule
33+
public final EnvironmentVariables envVarRule = new EnvironmentVariables();
34+
35+
@Rule public TestName name = new TestName();
36+
37+
@Test
38+
public void testImageWebPtoPNG() throws IOException {
39+
System.out.println(name.getMethodName());
40+
ClassLoader classLoader = getClass().getClassLoader();
41+
String imageFilename = new File(classLoader.getResource("sample.webp").getFile()).getAbsolutePath();
42+
43+
String imagepathPNG = ImageUtils.convertWebPtoPNG(imageFilename);
44+
assertTrue(Files.exists(Paths.get(imagepathPNG)));
45+
46+
String imageScale = Util.getImageScale(imagepathPNG, "100", "200");
47+
assertTrue(imageScale.equals("37"));
48+
}
49+
50+
@Test
51+
public void testImageBase64WebPtoPNG() throws IOException {
52+
System.out.println(name.getMethodName());
53+
ClassLoader classLoader = getClass().getClassLoader();
54+
String imageFilename = classLoader.getResource("sample.webp").getFile();
55+
byte[] imageContent = Files.readAllBytes(new File(imageFilename).toPath());
56+
String imageContentBase64 = "data:image/webp;base64," + Base64.getEncoder().encodeToString(imageContent);
57+
String imagePNGBase64 = ImageUtils.convertWebPtoPNG(imageContentBase64);
58+
assertTrue(imagePNGBase64.startsWith("data:image/png;base64,"));
59+
String imageScale = Util.getImageScale(imagePNGBase64, "100", "200");
60+
assertTrue(imageScale.equals("37"));
61+
}
62+
63+
}

src/test/resources/sample.webp

173 KB
Binary file not shown.

0 commit comments

Comments
 (0)