【发布时间】:2019-09-23 12:41:14
【问题描述】:
我有一堆 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 中)并将它们放入最后生成的文件中。
【问题讨论】:
-
我删除了我的答案,因为我认为它是错误的。
QSvgGenerator实际上应该或可以从 QPainter 编写矢量 SVG 文件(正如 Qt 示例所证明的那样)。因此,与图形视图、场景或所涉及的单个项目相关的事情肯定是发生了其他事情。如果您能提供一个更完整(但最小的:) 示例,我将有兴趣测试。 -
谢谢,我已经编辑了我的问题并制作了一个小应用程序来重现这种情况。
-
嗯,渲染的内容似乎很重要。使用您的示例,它甚至可以对我能找到的最简单的单色单路径 SVG 图标进行光栅化。如果我将 SVG 加载到
QIcon并使用它来绘制,则相同。 OTOH,如果我使用QSvgWidget加载图像,然后使用它渲染到QSvgRenderer,那么它会以矢量图形的形式出现!甚至是带有所有渐变的 PB 标志。此外,如果我将 SVG 加载到QSvgRenderer并使用它来渲染到生成器,它会输出矢量。所以这很奇怪,似乎与文档所声称的所有绘画都相同。 -
好的,有道理...与小部件/图标/等如何绘制自身有关。
QIcon使用位图绘画,这就是 SVG 生成器的输出。 QGraphicsItem 显然也是如此(因为它将自身缓存为像素图)。所以QSvgGenerator在这里结束:code.woboq.org/qt5/qtsvg/src/svg/… 而QWidgets 和QSvgRenderer直接将几何图形绘制到绘制设备(使用drawRect、drawText等等)。 -
刚刚想到了一些东西......而且它似乎有效!将
QGraphicsItem::cacheMode设置为QGraphicsItem::NoCache。因此,在您的示例中,我刚刚在创建QGraphicsSvgItem的位置下方添加了item->setCacheMode(QGraphicsItem::NoCache);,现在它以矢量格式保存。基本上,这样做是强制每次都完成绘画,而不是缓存在位图中。请确认,我们可以将其添加为答案。