From 24a0786d644c6fe434f79fbc153584fc86ab87c0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidtmer Date: Thu, 22 Aug 2019 16:28:23 +0200 Subject: [PATCH] When rescaling SVGs use the ViewBox, if defined, for default sizes --- .../imageio/plugins/svg/SVGImageReader.java | 11 +++- .../plugins/svg/SVGImageReaderTest.java | 55 +++++++++++++++++++ .../src/test/resources/svg/quadrants.svg | 13 +++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 imageio/imageio-batik/src/test/resources/svg/quadrants.svg diff --git a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java index 2727867f..cb2121d5 100755 --- a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java +++ b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java @@ -46,6 +46,7 @@ import org.apache.batik.gvt.renderer.ImageRendererFactory; import org.apache.batik.transcoder.*; import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.batik.util.ParsedURL; +import org.apache.batik.util.SVGConstants; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGSVGElement; @@ -326,7 +327,7 @@ public class SVGImageReader extends ImageReaderBase { // get the 'width' and 'height' attributes of the SVG document Dimension2D docSize = ctx.getDocumentSize(); - if (docSize != null) { + if (docSize != null) { defaultWidth = (float) docSize.getWidth(); defaultHeight = (float) docSize.getHeight(); } @@ -334,6 +335,14 @@ public class SVGImageReader extends ImageReaderBase { defaultWidth = 200; defaultHeight = 200; } + SVGSVGElement rootElement = svgDoc.getRootElement(); + String viewBoxStr = rootElement.getAttributeNS + (null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE); + if (viewBoxStr.length() != 0) { + float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null); + defaultWidth = rect[2]; + defaultHeight = rect[3]; + } // Hack to work around exception above if (root != null) { diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java index 0f086420..9cb379c3 100755 --- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java +++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java @@ -35,6 +35,7 @@ import org.junit.Ignore; import org.junit.Test; import javax.imageio.IIOException; +import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadWarningListener; @@ -43,9 +44,12 @@ import javax.imageio.stream.ImageInputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.ImagingOpException; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; +import java.nio.Buffer; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -99,6 +103,57 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest return Collections.singletonList("image/svg+xml"); } + @Test + public void testScaleViewBox() throws IOException { + URL svgUrl = getClassLoaderResource("/svg/quadrants.svg"); + + File tmpDir = new File(System.getProperty("java.io.tmpdir")); + + SVGImageReader reader = createReader(); + SVGReadParam param = new SVGReadParam(); + + int[] sizes = new int[]{16, 32, 64, 128}; + for (int size : sizes) { + try (InputStream svgStream = svgUrl.openStream(); ImageInputStream iis = ImageIO.createImageInputStream(svgStream)) { + reader.reset(); + reader.setInput(iis); + + + param.setSourceRenderSize(new Dimension(size, size)); + BufferedImage image = reader.read(0, param); + checkQuadrantColors(image); + } + finally { + reader.dispose(); + } + } + } + + private void checkQuadrantColors(BufferedImage image) { + int quadPoint = image.getWidth() / 2; + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + int current = image.getRGB(x, y); + if (x < quadPoint) { + if (y < quadPoint) { + assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF0000FF, current); + } + else { + assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFFFF0000, current); + } + } + else { + if (y < quadPoint) { + assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF00FF00, current); + } + else { + assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF000000, current); + } + } + } + } + } + @Test @Override public void testReadWithSizeParam() { diff --git a/imageio/imageio-batik/src/test/resources/svg/quadrants.svg b/imageio/imageio-batik/src/test/resources/svg/quadrants.svg new file mode 100644 index 00000000..b0527044 --- /dev/null +++ b/imageio/imageio-batik/src/test/resources/svg/quadrants.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file