QSvgGenerator 生成 Svg 时将 QSvgGraphicsItem 转换为图像 [英] QSvgGenerator converts QSvgGraphicsItem to image when generating Svg

查看:52
本文介绍了QSvgGenerator 生成 Svg 时将 QSvgGraphicsItem 转换为图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a bunch of SVG files that I've loaded them (as QGraphicsSvgItem) into a QGraphicsScene for designing and everything is Ok, now I want to save the scene into another output SVG file (including all the Svg items) with QSvgGenerator with the code below, but when it is exporting SVG items turn into images in the output file and their vectors are not anymore scalable.

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

I'm looking forward for XML-manipulation methods if there is no direct solution with this Qt framework.

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 项目的标签和节点(不将它们转换为图像数据)

I'm expecting an output svg file that contains tags and nodes of the included internal SVG items (not converting them to images data)

现在它正在将内部 svg 项目转换为这些图像标签:

right now it is converting internal svg items into these image tags:

<image x="131" y="127" width="102" height="102" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...

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

UPDATE 1 this tiny application will show an svg file (QGraphicsSvgItem) in the graphical scene and will use QSvgGenerator to export the scene into another output svg file:

#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 中)并将它们放入最后生成的文件中.

but what I get is an svg file includes converted corrupted bits of a very low quality image of the initial svg file. what I expect is that QSvgGenerator takes the initial svg elements from the source file (maybe saved in the QGraphicsSvgItem in the scene) and put them into the last generated file.

推荐答案

快速答案是在将每个 QGraphicsItem 渲染到 SVG* 之前禁用缓存模式.

The quick answer turned out to be disabling cache mode on each QGraphicsItem before rendering it to SVG*.

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

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

The reason is that when cache mode is enabled, the graphics item caches its painting in a bitmap image (which of course is raster format). So when asked to render itself on to the QSvgGenerator device, it just draws the cached bitmap. Which the generator correctly encodes as a bitmap image, not vectors.

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

This extends to any painting which uses bitmaps/QPixmap to paint or cache itself. For example QSvgIconEngine (which generates QIcons from SVG files) will use bitmaps for painting (even when the original source is a vector). So rendering a QIcon to QSvgGenerator produces raster images.

* 我会考虑启用缓存,只在渲染回 SVG 之前禁用它,然后重新启用.您必须遍历所有场景项目,但 OTOH 在其余时间使用缓存带来的性能提升可能远远超过这一点.

* I would consider leaving the cache enabled and only disabling it before rendering back to SVG, then re-enable after. You'd have to loop over all the scene items, but OTOH the performance gain with cache on the rest of the time could far outweigh that.

这篇关于QSvgGenerator 生成 Svg 时将 QSvgGraphicsItem 转换为图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆