QSvgGenerator在生成Svg时将QSvgGraphicsItem转为图像
QSvgGenerator converts QSvgGraphicsItem to image when generating Svg
我有一堆 SVG 文件,我已将它们(作为 QGraphicsSvgItem)加载到 QGraphicsScene 中进行设计,一切正常,现在我想将场景保存到另一个输出 SVG 文件(包括所有 Svg 项目) ) 使用 QSvgGenerator 和下面的代码,但是当它导出 SVG 项目时,输出文件中的项目变成图像并且它们的矢量不再可缩放。
如果这个 Qt 框架没有直接的解决方案,我期待 XML-操作方法。
QSvgGenerator generator;
generator.setFileName(savePath);
generator.setSize(QSize(static_cast<int>(currentScene->width()), static_cast<int>(currentScene->height())));
generator.setViewBox(currentScene->sceneRect());
generator.setTitle(tr("SVG Generated using SVG Generator"));
generator.setDescription(tr("an SVG drawing used by Software Package"));
QPainter painter;
painter.begin(&generator);
currentScene->clearSelection();
currentScene->render(&painter);
painter.end();
我期待一个输出 svg 文件,其中包含包含的内部 SVG 项目的标签和节点(不将它们转换为图像数据)
现在它正在将内部 svg 项目转换为这些图像标签:
<image x="131" y="127" width="102" height="102" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
更新 1
这个小应用程序将在图形场景中显示一个 svg 文件 (QGraphicsSvgItem),并将使用 QSvgGenerator 将场景导出到另一个输出 svg 文件:
#include <QApplication>
#include <QtSvg>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Creating and showing an svg icon in the graphical scene view
QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
QGraphicsScene *scene = new QGraphicsScene;
scene->setSceneRect(0, 0, 1000, 1000);
QGraphicsView *view = new QGraphicsView(scene);
scene->addItem(item);
item->setPos(view->rect().center());
view->show();
// Saving the graphical scene to another svg output device file using QSvgGenerator
QSvgGenerator generator;
generator.setFileName("output.svg");
generator.setSize(QSize(static_cast<int>(scene->width()), static_cast<int>(scene->height())));
generator.setViewBox(scene->sceneRect());
generator.setTitle("SVG Generated using SVG Generator");
generator.setDescription("an SVG drawing used by Software Package");
QPainter painter;
painter.begin(&generator);
scene->clearSelection();
scene->render(&painter);
painter.end();
return a.exec();
}
但我得到的是一个 svg 文件,其中包含初始 svg 文件的非常低质量图像的转换损坏位。
我期望的是 QSvgGenerator 从源文件中获取初始 svg 元素(可能保存在场景中的 QGraphicsSvgItem 中)并将它们放入最后生成的文件中。
快速回答是在将每个 QGraphicsItem
呈现为 SVG* 之前禁用缓存模式。
QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
item->setCacheMode(QGraphicsItem::NoCache);
原因是当启用缓存模式时,图形项将其绘制缓存在位图图像(当然是光栅格式)中。因此,当要求将自身呈现到 QSvgGenerator
设备上时,它只绘制缓存的位图。生成器将其正确编码为位图图像,而不是矢量。
这扩展到任何使用 bitmaps/QPixmap 来绘制或缓存自身的绘画。例如 QSvgIconEngine
(从 SVG 文件生成 QIcon
s)将使用位图进行绘画(即使原始源是矢量)。因此,将 QIcon 渲染到 QSvgGenerator 会生成光栅图像。
* 我会考虑启用缓存,只在渲染回 SVG 之前禁用它,然后再重新启用。您必须遍历所有场景项,但 OTOH 在其余时间使用缓存的性能增益可能远远超过它。
我有一堆 SVG 文件,我已将它们(作为 QGraphicsSvgItem)加载到 QGraphicsScene 中进行设计,一切正常,现在我想将场景保存到另一个输出 SVG 文件(包括所有 Svg 项目) ) 使用 QSvgGenerator 和下面的代码,但是当它导出 SVG 项目时,输出文件中的项目变成图像并且它们的矢量不再可缩放。
如果这个 Qt 框架没有直接的解决方案,我期待 XML-操作方法。
QSvgGenerator generator;
generator.setFileName(savePath);
generator.setSize(QSize(static_cast<int>(currentScene->width()), static_cast<int>(currentScene->height())));
generator.setViewBox(currentScene->sceneRect());
generator.setTitle(tr("SVG Generated using SVG Generator"));
generator.setDescription(tr("an SVG drawing used by Software Package"));
QPainter painter;
painter.begin(&generator);
currentScene->clearSelection();
currentScene->render(&painter);
painter.end();
我期待一个输出 svg 文件,其中包含包含的内部 SVG 项目的标签和节点(不将它们转换为图像数据)
现在它正在将内部 svg 项目转换为这些图像标签:
<image x="131" y="127" width="102" height="102" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
更新 1 这个小应用程序将在图形场景中显示一个 svg 文件 (QGraphicsSvgItem),并将使用 QSvgGenerator 将场景导出到另一个输出 svg 文件:
#include <QApplication>
#include <QtSvg>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Creating and showing an svg icon in the graphical scene view
QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
QGraphicsScene *scene = new QGraphicsScene;
scene->setSceneRect(0, 0, 1000, 1000);
QGraphicsView *view = new QGraphicsView(scene);
scene->addItem(item);
item->setPos(view->rect().center());
view->show();
// Saving the graphical scene to another svg output device file using QSvgGenerator
QSvgGenerator generator;
generator.setFileName("output.svg");
generator.setSize(QSize(static_cast<int>(scene->width()), static_cast<int>(scene->height())));
generator.setViewBox(scene->sceneRect());
generator.setTitle("SVG Generated using SVG Generator");
generator.setDescription("an SVG drawing used by Software Package");
QPainter painter;
painter.begin(&generator);
scene->clearSelection();
scene->render(&painter);
painter.end();
return a.exec();
}
但我得到的是一个 svg 文件,其中包含初始 svg 文件的非常低质量图像的转换损坏位。 我期望的是 QSvgGenerator 从源文件中获取初始 svg 元素(可能保存在场景中的 QGraphicsSvgItem 中)并将它们放入最后生成的文件中。
快速回答是在将每个 QGraphicsItem
呈现为 SVG* 之前禁用缓存模式。
QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
item->setCacheMode(QGraphicsItem::NoCache);
原因是当启用缓存模式时,图形项将其绘制缓存在位图图像(当然是光栅格式)中。因此,当要求将自身呈现到 QSvgGenerator
设备上时,它只绘制缓存的位图。生成器将其正确编码为位图图像,而不是矢量。
这扩展到任何使用 bitmaps/QPixmap 来绘制或缓存自身的绘画。例如 QSvgIconEngine
(从 SVG 文件生成 QIcon
s)将使用位图进行绘画(即使原始源是矢量)。因此,将 QIcon 渲染到 QSvgGenerator 会生成光栅图像。
* 我会考虑启用缓存,只在渲染回 SVG 之前禁用它,然后再重新启用。您必须遍历所有场景项,但 OTOH 在其余时间使用缓存的性能增益可能远远超过它。