在 QImage 上渲染一个大的 QGraphicsScene 会剪掉它
Rendering a large QGraphicsScene on a QImage clips it off
我正在创建一些渲染 QGraphicsScene
内容的图像。
我的项目要求是它应该处理 10 英尺乘 8 英寸的 canvas 尺寸。在屏幕和场景大小上,即 8640 x 576 像素。
我可以很好地渲染它。
问题是,输出图像需要有 300 分辨率。
这意味着,渲染图像的宽度为 36000,超过 2^15 - 1 = 32767
像素.....
输出被裁剪 - 在下面的代码中,我会得到正确预期大小 (36000) 的 QImage
,但 QGraphicsScene
仅呈现 32767 像素。
这令人困惑...我无法解释结果 - 如果 QImage
限制为 32767 像素,那么我一开始就无法创建一个。但我查了一下 QImage
"sanity check" 高得多。
创建图像后,我在渲染代码中看不到任何内容 QGraphicsScene
会裁剪任何值....
这是一个试图暴露我的问题的简单代码。
它创建一个所需大小的 QImage
,并填充黄色(用于控制)。
然后它会呈现一个 QGraphicsScene
,带有蓝色背景画笔和靠近右边距的红色矩形。
如果它工作正常,结果应该是:一个宽度为 36000 的蓝色图像,最右边有一个红色的小矩形。
但是...实际上,结果是一个宽度为 36000 的图像,前 32766 个像素为蓝色,其余为黄色,没有红色矩形。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QPainter>
void printScene(QGraphicsScene* s, qreal ratio) {
qreal w = s->width() * ratio;
qreal h = s->height() * ratio;
QRectF target(0, 0, w, h);
QImage image = QImage(w, h, QImage::Format_ARGB32_Premultiplied);
image.fill(QColor(Qt::yellow).rgb());
QPainter painter;
painter.begin(&image);
s->render(&painter, target);
painter.end();
image.save("image.png");
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene s;
s.setSceneRect(0, 0, 8640, 576);
s.setBackgroundBrush(Qt::blue);
QGraphicsView view(&s);
view.show();
QGraphicsRectItem* r = s.addRect(8530, 250, 100, 100);
r->setBrush(Qt::red);
qreal ratio = 300/72.;
printScene(&s, ratio);
return app.exec();
}
如示例图片所示,QImage
创建成功,QGraphicsScene
虽然只渲染到 2^15 - 1
...但我逐步查看了他们的代码,但我没有看到它停止了....
(我也尝试创建原始场景 36000 x 一些东西(并将 ratio
设置为 1),它显示正常......它不会渲染到 QImage
任何超出32767 像素)
我是不是漏掉了一些设置? QGraphicsScene::render()
不渲染更多的原因可能是什么?
我很想知道如何渲染我想要的尺寸 - 36000 像素的宽度 - 或者这是不可能的原因。
我是 运行 这个 Windows 7, 32 位 Qt 5.5.1 或 4.7.4
我找到了剪裁的原因 - 并设想了 2 个解决方法。
为什么:
单步执行渲染代码,剪辑矩形限制为 32767:
bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op)
{
Q_D(QRasterPaintEngine);
QRect clipRect = r & d->deviceRect;
...
}
其中 deviceRect
由
设置
void QRasterPaintEnginePrivate::systemStateChanged()
{
deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
...
}
和
// This limitations comes from qgrayraster.c. Any higher and
// rasterization of shapes will produce incorrect results.
const int QT_RASTER_COORD_LIMIT = 32767;
选项:
1) 渲染至最大 32767,如果目标必须更大,则缩放结果。 (应该给出略低的质量)
2) 创建 2 个图像并将它们组合(我仍然需要弄清楚,但我认为这是更好的解决方法)
我正在创建一些渲染 QGraphicsScene
内容的图像。
我的项目要求是它应该处理 10 英尺乘 8 英寸的 canvas 尺寸。在屏幕和场景大小上,即 8640 x 576 像素。
我可以很好地渲染它。
问题是,输出图像需要有 300 分辨率。
这意味着,渲染图像的宽度为 36000,超过 2^15 - 1 = 32767
像素.....
输出被裁剪 - 在下面的代码中,我会得到正确预期大小 (36000) 的 QImage
,但 QGraphicsScene
仅呈现 32767 像素。
这令人困惑...我无法解释结果 - 如果 QImage
限制为 32767 像素,那么我一开始就无法创建一个。但我查了一下 QImage
"sanity check" 高得多。
创建图像后,我在渲染代码中看不到任何内容 QGraphicsScene
会裁剪任何值....
这是一个试图暴露我的问题的简单代码。
它创建一个所需大小的 QImage
,并填充黄色(用于控制)。
然后它会呈现一个 QGraphicsScene
,带有蓝色背景画笔和靠近右边距的红色矩形。
如果它工作正常,结果应该是:一个宽度为 36000 的蓝色图像,最右边有一个红色的小矩形。
但是...实际上,结果是一个宽度为 36000 的图像,前 32766 个像素为蓝色,其余为黄色,没有红色矩形。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QPainter>
void printScene(QGraphicsScene* s, qreal ratio) {
qreal w = s->width() * ratio;
qreal h = s->height() * ratio;
QRectF target(0, 0, w, h);
QImage image = QImage(w, h, QImage::Format_ARGB32_Premultiplied);
image.fill(QColor(Qt::yellow).rgb());
QPainter painter;
painter.begin(&image);
s->render(&painter, target);
painter.end();
image.save("image.png");
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene s;
s.setSceneRect(0, 0, 8640, 576);
s.setBackgroundBrush(Qt::blue);
QGraphicsView view(&s);
view.show();
QGraphicsRectItem* r = s.addRect(8530, 250, 100, 100);
r->setBrush(Qt::red);
qreal ratio = 300/72.;
printScene(&s, ratio);
return app.exec();
}
如示例图片所示,QImage
创建成功,QGraphicsScene
虽然只渲染到 2^15 - 1
...但我逐步查看了他们的代码,但我没有看到它停止了....
(我也尝试创建原始场景 36000 x 一些东西(并将 ratio
设置为 1),它显示正常......它不会渲染到 QImage
任何超出32767 像素)
我是不是漏掉了一些设置? QGraphicsScene::render()
不渲染更多的原因可能是什么?
我很想知道如何渲染我想要的尺寸 - 36000 像素的宽度 - 或者这是不可能的原因。
我是 运行 这个 Windows 7, 32 位 Qt 5.5.1 或 4.7.4
我找到了剪裁的原因 - 并设想了 2 个解决方法。
为什么:
单步执行渲染代码,剪辑矩形限制为 32767:
bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op)
{
Q_D(QRasterPaintEngine);
QRect clipRect = r & d->deviceRect;
...
}
其中 deviceRect
由
void QRasterPaintEnginePrivate::systemStateChanged()
{
deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
...
}
和
// This limitations comes from qgrayraster.c. Any higher and
// rasterization of shapes will produce incorrect results.
const int QT_RASTER_COORD_LIMIT = 32767;
选项:
1) 渲染至最大 32767,如果目标必须更大,则缩放结果。 (应该给出略低的质量)
2) 创建 2 个图像并将它们组合(我仍然需要弄清楚,但我认为这是更好的解决方法)