TwelveMonkeys: SVG Image size problem
Hello,
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)
}
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 20 (10 by maintainers)
Commits related to this issue
- #518 Parsing SVG width/height attributes — committed to Schmidor/TwelveMonkeys by Schmidor 4 years ago
- #518 Fallbacks for aspect ratio, if only one dimension is given — committed to Schmidor/TwelveMonkeys by Schmidor 4 years ago
- #518 Fallbacks for aspect ratio, if only one dimension is given — committed to Schmidor/TwelveMonkeys by Schmidor 4 years ago
- Merge pull request #522 from Schmidor/svg_size #518 Parsing SVG width/height attributes — committed to haraldk/TwelveMonkeys by haraldk 4 years ago
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_heightor
missing height = vb_height * width / vb_widthBut I don’t know what happens when
preserveAspectRatio="none"is used or if no viewbox is defined (defaults to 0 0 300? 150?).