QSvgGenerator生成Svg时将QSvgGraphicsItem转换为图像

时间:2019-09-23 12:41:14

标签: c++ qt svg qtsvg

我有一堆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中),并将它们放入最后生成的文件中。

1 个答案:

答案 0 :(得分:1)

快速答案原来是在将每个QGraphicsItem呈现为SVG *之前禁用每个缓存模式。

QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
item->setCacheMode(QGraphicsItem::NoCache);

原因是,启用缓存模式后,图形项会将其绘画内容缓存在位图图像(当然是光栅格式)中。因此,当要求将自身呈现到QSvgGenerator设备上时,它只是绘制缓存的位图。生成器将其正确编码为位图图像,而不是矢量。

这扩展到使用位图/ QPixmap绘画或缓存自身的任何绘画。例如,QSvgIconEngine(从SVG文件生成QIcon)将使用位图进行绘制(即使原始源是矢量)。因此,将QIcon渲染到QSvgGenerator会生成光栅图像。

*我会考虑将缓存保持启用状态,并且仅在将其渲染回SVG之前将其禁用,然后再重新启用。您必须遍历所有场景项,但是OTOH在其余时间使用缓存获得的性能提升可能远远超过这一点。