首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QSvgGenerator在生成Svg时将QSvgGraphicsItem转换为图像

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

Stack Overflow用户
提问于 2019-09-23 12:41:14
回答 1查看 651关注 0票数 2

我有一堆SVG文件,我已经将它们(作为QGraphicsSvgItem)加载到QGraphicsScene中进行设计,一切都很好,现在我想用下面的代码将场景保存到另一个带有QSvgGenerator的输出SVG文件(包括所有Svg项)中,但是当它导出SVG项时,就会变成输出文件中的图像,并且它们的向量不再是可伸缩的。

如果没有这个Qt框架的直接解决方案,我期待XML操作方法。

代码语言:javascript
复制
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项转换为以下图像标记:

代码语言:javascript
复制
<image x="131" y="127" width="102" height="102" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...

更新1这个小应用程序将在图形场景中显示一个svg文件(QGraphicsSvgItem),并使用QSvgGenerator将场景导出到另一个输出svg文件:

代码语言:javascript
复制
#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中),并将它们放入最后生成的文件中。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-24 23:17:26

快速回答是在每个QGraphicsItem上禁用缓存模式,然后再将其呈现给SVG*。

代码语言:javascript
复制
QGraphicsSvgItem *item = new QGraphicsSvgItem(":The Pirate Bay Logo.svg");
item->setCacheMode(QGraphicsItem::NoCache);

原因是当启用缓存模式时,图形项以位图图像(当然是光栅格式)缓存其绘图。因此,当被要求将自己呈现到QSvgGenerator设备上时,它只绘制缓存的位图。生成器正确地将其编码为位图图像,而不是向量。

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

*我会考虑让缓存处于启用状态,并且只在呈现回SVG之前禁用它,然后再重新启用它。您必须遍历所有场景项,但是OTOH在其余时间使用缓存所获得的性能收益可能远远超过这一点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58062699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档