将 QGraphicsScene 保存到 Svg 更改缩放
Saving a QGraphicsScene to Svg changes scaling
我需要将 QGraphicsScene
中的项目保存到 svg 中,并能够在场景中加载该 svg。
我可以的...
但是每次 canvas 保存到 svg 时,项目在加载时都会变大(重复保存和加载相同的 svg 会导致它变大)。
我找不到原因。
我附上示例代码 - 和结果。
test1.pro
QT += gui svg
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core
TARGET = test1
TEMPLATE = app
SOURCES += \
svggenerator.cpp
svggenerator.cpp
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsEllipseItem>
#include <QGraphicsSvgItem>
#include <QSvgGenerator>
#include <QSvgRenderer>
#include <QFile>
#include <QByteArray>
#include <QMessageBox>
void saveSceneToSvg(QGraphicsScene* s, const QString &filename) {
QRectF newSceneRect;
QGraphicsScene *tempScene = new QGraphicsScene(s->sceneRect());
tempScene->setBackgroundBrush(QBrush(Qt::transparent));
tempScene->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
foreach(QGraphicsItem* item, s->items()) {
newSceneRect |= item->mapToScene(item->boundingRect()).boundingRect();
tempScene->addItem(item);
}
tempScene->setSceneRect(newSceneRect);
tempScene->clearSelection();
QSize sceneSize = newSceneRect.size().toSize();
QSvgGenerator generator;
generator.setFileName(filename);
generator.setSize(sceneSize);
generator.setViewBox(QRect(0, 0, sceneSize.width(), sceneSize.height()));
generator.setDescription(QObject::tr("My canvas exported to Svg"));
generator.setTitle(filename);
QPainter painter;
painter.begin(&generator);
tempScene->render(&painter);
painter.end();
tempScene->clear();
delete tempScene;
}
void loadSvg(QGraphicsScene* s, const QString &filename, const QPointF& p) {
QGraphicsSvgItem* item = new QGraphicsSvgItem();
QFile file(filename);
file.open(QFile::ReadOnly);
QByteArray contents = file.readAll();
item->setSharedRenderer(new QSvgRenderer(contents));
file.close();
item->setPos(p);
s->addItem(item);
}
void processScene(QGraphicsScene* s) {
QGraphicsEllipseItem* eli = new QGraphicsEllipseItem();
eli->setRect(QRectF(0, 0, 100, 100));
eli->setPen(Qt::NoPen);
eli->setBrush(Qt::red);
eli->setPos(100, 300);
s->addItem(eli);
QGraphicsEllipseItem* eli1 = new QGraphicsEllipseItem();
eli1->setRect(QRectF(0, 0, 100, 100));
eli1->setPen(Qt::NoPen);
eli1->setBrush(Qt::yellow);
eli1->setPos(150, 300);
s->addItem(eli1);
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd.svg");
loadSvg(s, "abcd.svg", QPointF(100,300));
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd1.svg"); // saved with a dif name so I can see
loadSvg(s, "abcd1.svg", QPointF(100,300));
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd2.svg");
loadSvg(s, "abcd2.svg", QPointF(100,300));
// .... each time i call them they grow larger
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene s;
s.setSceneRect(50, 0, 1000, 800);
QGraphicsView view(&s);
view.show();
processScene(&s);
return app.exec();
}
结果:
查看 svgs 本身,我可以看到 svgs 的大小增加了大约 1.25...我无法解释,也不能确定其他示例是否如此。 (好像)
是什么导致了这种增长?我怎样才能阻止它?
(我还注意到顺序不同......我只是注意到这是一个不同的问题......但是因为在我的 "real" 代码中我也有 z 顺序我不在乎。)
保存我认为很好 - 生成的 svg 具有预期大小的大小和视图框。
加载其他 svg 没问题 - 从外部源保存 svg 会创建大小相似的 svg。
似乎问题是当我加载由 svg 生成器创建的 svg 时,它的大小增加了。
(如果我能确定情况总是如此,我可以尝试按比例缩小它的负载,但每次比率都不完全是 1.25,但关闭...而且我不知道如何告诉外部 svg 和生成的 svg 之间的区别)。
看起来像是SvgGenerator 的一个bug。您提供给 SVG 生成器的大小仅用于构成 svg 的 header。 .svg 文件的实际大小与 header 中所写的不同。我发现的唯一解决方法是在保存时将大小简单地减少 25%,类似于:
int width = qCeil(qreal(sceneSize.width()/1.25));
int height = qCeil(qreal(sceneSize.height()/1.25));
generator.setSize(QSize(width, height));
generator.setViewBox(QRect(0, 0, width, height));
我需要将 QGraphicsScene
中的项目保存到 svg 中,并能够在场景中加载该 svg。
我可以的...
但是每次 canvas 保存到 svg 时,项目在加载时都会变大(重复保存和加载相同的 svg 会导致它变大)。
我找不到原因。
我附上示例代码 - 和结果。
test1.pro
QT += gui svg
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core
TARGET = test1
TEMPLATE = app
SOURCES += \
svggenerator.cpp
svggenerator.cpp
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsEllipseItem>
#include <QGraphicsSvgItem>
#include <QSvgGenerator>
#include <QSvgRenderer>
#include <QFile>
#include <QByteArray>
#include <QMessageBox>
void saveSceneToSvg(QGraphicsScene* s, const QString &filename) {
QRectF newSceneRect;
QGraphicsScene *tempScene = new QGraphicsScene(s->sceneRect());
tempScene->setBackgroundBrush(QBrush(Qt::transparent));
tempScene->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
foreach(QGraphicsItem* item, s->items()) {
newSceneRect |= item->mapToScene(item->boundingRect()).boundingRect();
tempScene->addItem(item);
}
tempScene->setSceneRect(newSceneRect);
tempScene->clearSelection();
QSize sceneSize = newSceneRect.size().toSize();
QSvgGenerator generator;
generator.setFileName(filename);
generator.setSize(sceneSize);
generator.setViewBox(QRect(0, 0, sceneSize.width(), sceneSize.height()));
generator.setDescription(QObject::tr("My canvas exported to Svg"));
generator.setTitle(filename);
QPainter painter;
painter.begin(&generator);
tempScene->render(&painter);
painter.end();
tempScene->clear();
delete tempScene;
}
void loadSvg(QGraphicsScene* s, const QString &filename, const QPointF& p) {
QGraphicsSvgItem* item = new QGraphicsSvgItem();
QFile file(filename);
file.open(QFile::ReadOnly);
QByteArray contents = file.readAll();
item->setSharedRenderer(new QSvgRenderer(contents));
file.close();
item->setPos(p);
s->addItem(item);
}
void processScene(QGraphicsScene* s) {
QGraphicsEllipseItem* eli = new QGraphicsEllipseItem();
eli->setRect(QRectF(0, 0, 100, 100));
eli->setPen(Qt::NoPen);
eli->setBrush(Qt::red);
eli->setPos(100, 300);
s->addItem(eli);
QGraphicsEllipseItem* eli1 = new QGraphicsEllipseItem();
eli1->setRect(QRectF(0, 0, 100, 100));
eli1->setPen(Qt::NoPen);
eli1->setBrush(Qt::yellow);
eli1->setPos(150, 300);
s->addItem(eli1);
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd.svg");
loadSvg(s, "abcd.svg", QPointF(100,300));
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd1.svg"); // saved with a dif name so I can see
loadSvg(s, "abcd1.svg", QPointF(100,300));
QMessageBox::information(NULL, "hi", "click");
saveSceneToSvg(s, "abcd2.svg");
loadSvg(s, "abcd2.svg", QPointF(100,300));
// .... each time i call them they grow larger
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene s;
s.setSceneRect(50, 0, 1000, 800);
QGraphicsView view(&s);
view.show();
processScene(&s);
return app.exec();
}
结果:
查看 svgs 本身,我可以看到 svgs 的大小增加了大约 1.25...我无法解释,也不能确定其他示例是否如此。 (好像)
是什么导致了这种增长?我怎样才能阻止它?
(我还注意到顺序不同......我只是注意到这是一个不同的问题......但是因为在我的 "real" 代码中我也有 z 顺序我不在乎。)
保存我认为很好 - 生成的 svg 具有预期大小的大小和视图框。
加载其他 svg 没问题 - 从外部源保存 svg 会创建大小相似的 svg。
似乎问题是当我加载由 svg 生成器创建的 svg 时,它的大小增加了。
(如果我能确定情况总是如此,我可以尝试按比例缩小它的负载,但每次比率都不完全是 1.25,但关闭...而且我不知道如何告诉外部 svg 和生成的 svg 之间的区别)。
看起来像是SvgGenerator 的一个bug。您提供给 SVG 生成器的大小仅用于构成 svg 的 header。 .svg 文件的实际大小与 header 中所写的不同。我发现的唯一解决方法是在保存时将大小简单地减少 25%,类似于:
int width = qCeil(qreal(sceneSize.width()/1.25));
int height = qCeil(qreal(sceneSize.height()/1.25));
generator.setSize(QSize(width, height));
generator.setViewBox(QRect(0, 0, width, height));