Unable to get internal image elements rendered with Qt6.9.2 QSvgRenderer to maintain aspect ratio

2 weeks ago 14
ARTICLE AD BOX

A little background. I had been using Qt5.15 in conjunction with WebKit to do svg renderering to .png images in the past, and decided to update to Qt6. As part of this decision, I also wanted to get away from using .js code and reduce the required qt dlls.

Using QSvgRenderer seemed like the best fit, since it eliminated the complexity of needing to utilize page views.

However, image elements don't seem to be honoring the default aspect ratio that svg is built with (xMidYMid meet). It instead seems to be using 'none'. Even worse, when explicitly setting the preserveAspectRatio to 'xMidYMid meet', it seems to override to 'none'. Am I doing something wrong in my implementation of Qt6?

Example svg (embedded jpeg is a horizontal rectangle with an image of an angled black and white pencil:

<?xml version='1.0' encoding='UTF-8' standalone='no'?> <svg color-interpolation-filters="sRGB" height="500" viewBox="0.0 0.0 500 500" width="500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g class="jpegImage" display="inline" id="photo1"> <image height="100" width="100" x="5" xlink:href="data:image/jpeg;base64,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" y="5"/> </g> </svg>

When saved as a .svg file and open through Chrome/Edge, it looks like (note that this is a screenshot):

Square image with pencil image using correct aspect ratio. Not stretched vertically. enter image description here

Code:

QDomDocument m_doc; m_doc.setContent(mySvg.toVariant().toByteArray());       QByteArray svgData = m_doc.toByteArray();       QSvgRenderer renderer(svgData);       renderer.setAspectRatioMode(Qt::KeepAspectRatio);       QSize renderSize = renderer.defaultSize();       QImage image(200, 200, QImage::Format_ARGB32_Premultiplied);       int dpmx = 300 * 100 / 2.54;       int dpmy = 300 * 100 / 2.54;       image.setDotsPerMeterX(dpmx);       image.setDotsPerMeterY(dpmy);       image.fill(Qt::white);       QPainter painter(&image);       renderer.render(&painter);       painter.end();       svgData.clear();       QString fName = "C:\\temp\\jtest\\image.png";       bool ok = image.save(fName, "PNG", 89);

Now when rendered through QSvgRenderer it looks like:

Embedded image now being stretched to fit in the 100x100 image element instead of maintaining aspect ratio. enter image description here

Is there a rendering option I'm missing to get the QSvgRenderer to render like a browser?

Read Entire Article