SVG Image size problem
See original GitHub issueHello,
First, thank for the update! The ICO write support is very welcome 😃
But, after updating from imageio-batik-3.4.2 to imageio-batik-3.5 I’m having problems resizing SVG images. Most likely, it is related to this update: When rescaling SVGs use the ViewBox, if defined, for default sizes
Now to describe my problem: I do a bit of cheating to zoom SVG images. Every time the user changes the zoom in my viewer, I modify the XML data (width and height) and pass this new document to the reader to generate a new image. This way, the image is always zoomed with awesome SVG quality instead of using conventional raster zooming.
No need to say, in 3.4.2 all worked 100%. This is what I do:
NodeList svgNodes = svgXML.getElementsByTagName("svg");
if (svgNodes != null && svgNodes.getLength() > 0) {
Node node = svgNodes.item(0);
if (node instanceof Element) {
String viewBox = ((Element) node).getAttribute("viewBox");
if (viewBox.isEmpty()) {
// If no view box is in the original, there will be problems.
// Set a default one.
((Element) node).setAttribute("viewBox", "0 0 " + widthPX + " " + heightPX);
}
((Element) node).setAttribute("width", String.valueOf(widthPX));
((Element) node).setAttribute("height", String.valueOf(heightPX));
success = true;
}
}
In 3.5, it all becomes messed up. I think 3.4.2 was actually correct and 3.5 is wrong, because if you open the images in browsers they will have the same size as in 3.4.2 (unless XML has no width/height specified in which the browser will have the size in relation to the available size inside the element but in my viewer I’ll default it to 400px).
I think you’ll be able to see the problem if you create copy of your SVG and try to double the size of the image. In 3.5, it is impossible because it ignores width/height, you’ll need to halve the viewport but then the image gets cut.
I think the problem would be solved if you change the reader code to this (which makes much more sense to me):
// get the 'width' and 'height' attributes of the SVG document
Dimension2D docSize = ctx.getDocumentSize();
if (docSize != null) {
defaultWidth = (float) docSize.getWidth();
defaultHeight = (float) docSize.getHeight();
}
else {
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];
}
else {
defaultWidth = 200; //maybe 400 is better (not too small/big)
defaultHeight = 200; //maybe 400 is better (not too small/big)
}
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:20 (10 by maintainers)
Top GitHub Comments
I’ve added some of those corner cases with fallbacks. If we don’t get sample images that show otherwise it should do for now 😃
Thanks! I’ll test with this new JAR and will report back very soon.
The browser calculates the missing dimension to keep aspect ratio. It must be from the viewbox ratio:
missing width = vb_width * height / vb_height
or
missing height = vb_height * width / vb_width
But I don’t know what happens when
preserveAspectRatio="none"
is used or if no viewbox is defined (defaults to 0 0 300? 150?).