QSvgGenerator преобразует QSvgGraphicsItem в изображение при генерации Svg - PullRequest
1 голос
/ 23 сентября 2019

У меня есть куча файлов SVG, которые я загрузил (как QGraphicsSvgItem) в QGraphicsScene для проектирования, и все в порядке, теперь я хочу сохранить сцену в другой выходной файл SVG (включая все элементы Svg) с помощьюQSvgGenerator с кодом ниже, но когда он экспортирует элементы SVG, они превращаются в изображения в выходном файле, и их векторы больше не масштабируются.

Я с нетерпением жду методов XML-манипуляции, если прямого решения не существуетс этой средой Qt.

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 Ответ

1 голос
/ 25 сентября 2019

Быстрым ответом оказалось отключение режима кэширования на каждом QGraphicsItem перед его рендерингом в SVG *.

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

Причина в том, что при включенном режиме кэширования графический элемент кэширует свою отрисовкув растровом изображении (что, конечно, в растровом формате).Поэтому, когда его просят отрисовать себя на устройстве QSvgGenerator, он просто рисует кэшированное растровое изображение.Который генератор правильно кодирует как растровое изображение, а не векторы.

Это распространяется на любое рисование, которое использует растровые изображения / QPixmap для рисования или кэширования себя.Например, QSvgIconEngine (который генерирует QIcon s из файлов SVG) будет использовать растровые изображения для рисования (даже если исходным источником является вектор).Таким образом, рендеринг QIcon в QSvgGenerator приводит к созданию растровых изображений.

* Я бы хотел оставить кэш включенным и отключить его только перед рендерингом в SVG, а затем снова включить после него.Вам придется перебирать все элементы сцены, но в остальном выигрыш в производительности с кешем в остальное время может значительно перевесить это.

...