0

I am working on an application that requires a server request for an SVG that is representative of a particular product configuration. This is my first time dealing with SVG and I am hung up on decoding the server response in such a way where the image can be displayed with a QSvgRenderer. Something like this

QByteArray panelData(QS.toStdString().c_str(), QS.length());
QSvgRenderer renderSVG(panelData);
QImage image(500, 200, QImage::Format_ARGB32);
QPainter painter(&image);
renderSVG.render(&painter);

I also thought about going the qpixmap on qlabel route like this.

QPixmap pix;
pix.fromImage(image);
ui->PixLabel->setPixmap(QPixmap::fromImage(image));

I have attempted using QTextdocument::toHtml as others have suggested but only end up trading one set of decoding problems for others. Do the qt libraries have a direct way of rendering the response below?

A server reply in part...

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="307px" height="625px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="P-mlvr" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" style="stop-color:#f0f0f0;stop-opacity:1;" /> <stop offset="0.0625" style="stop-color:#e0e0e0;stop-opacity:1;" /> <stop offset="100%" style="stop-color:#d0d0d0;stop-opacity:1;" /> </linearGradient> <linearGradient id="P-flvr" x1="0%" y1="100%" x2="0%" y2="0%"> <stop offset="0%" style="stop-color:#b0b0b0;stop-opacity:1;" /> <stop offset="0.0625" style="stop-color:#e0e0e0;stop-opacity:1;" /> <stop offset="75%" style="stop-color:#e0e0e0;stop-opacity:1;" /> <stop offset="100%" style="stop-color:#d0d0d0;stop-opacity:1;>

6
  • The string you're showing is a plain svg descriptor, if you manage to correctly extract it in QS your first code snippet seems legit: what's not working? Commented Apr 6, 2021 at 16:58
  • The first thing I tried was feeding the above response directly into the SVG Renderer and all I got was a blank image. Maybe extracting to the QByteArray is incorrect. Commented Apr 7, 2021 at 1:05
  • I have tried a number of variants of RenderSVG.load(panelData) changing the decoding of panelData. All return false. Commented Apr 7, 2021 at 2:57
  • Just to see if there's a problem with encoding, can you try to take the QByteArray containing the svg (<xml ...<svg...</svg> part), save to file ex. test.svg and open it with a svg viewer (ex. browser) to check if it's valid? Commented Apr 7, 2021 at 5:59
  • the server reply looks incomplete, or you are pasting a part of it. save the response to a file and attach it to your question. you may want to save it with .svg extension and try open it with your browser first Commented Apr 7, 2021 at 6:06

2 Answers 2

0

Assuming that the QByteArray is valid (svg xml descriptor coherent and complete, encoding handled correctly), this is working:

QString QS = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
             "<svg version=\"1.1\" viewBox=\"0 0 500 500\" width=\"500px\" height=\"500px\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
             "<title>Test</title>"
             "<rect x=\"100\" y=\"100\" width=\"100\" height=\"100\" stroke=\"blue\" fill=\"purple\" fill-opacity=\"0.5\" stroke-opacity=\"0.8\"/>"
             "</svg>";
QByteArray panelData(QS.toStdString().c_str(), QS.length());
QSvgRenderer renderSVG(panelData);
QImage image(500, 500, QImage::Format_ARGB32_Premultiplied);
QPainter painter(&image);
renderSVG.render(&painter);
bool res = image.save("D:\\HD\\Desktop\\svg.png");
Sign up to request clarification or add additional context in comments.

Comments

0

After a number of tests, I discovered the problem originated with the encoding. QSvgRenderer does not have the ability to decode the server response directly, which was causing renderSVG.load() to fail. I had to use QTextDocument's decoding function to decode the resposne in such a way where QSvgRenderer can read it.

QString QS = QString::fromUtf8(serverReply.c_str());
QTextDocument text;
text.setHtml(QS);
QString plain = text.toPlainText();
QByteArray panelData(QByteArray::fromStdString(plain.toStdString()));

QSvgRenderer renderSVG;
renderSVG.load(panelData);
QPixmap pix(RenderSVG.defaultSize());
QPainter pixPainter(&pix);
renderSVG.render(&pixPainter);
ui->pixLabel->setPixmap(pix);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.