我正在创建一些渲染QGraphicsScene
内容的图像
我的项目要求是它应该处理10英尺乘8英寸的画布尺寸。屏幕和场景大小,即8640 x 576像素
我可以把它渲染得很好。
问题是,输出图像需要有300分辨率
这意味着,渲染图像的宽度为36000,超过2^15 - 1 = 32767
像素.....
输出被剪裁 - 在下面的代码中,我会得到正确预期大小的QImage
(36000),但QGraphicsScene
仅渲染到32767像素。
这令人困惑......我无法解释结果 - 如果QImage
限制是32767像素,那么我不应该首先创建一个。但我检查了QImage
"健全检查"要高得多。
创建图像后,我在代码中看不到任何会剪切任何值的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
中运行它答案 0 :(得分:0)
我找到了剪辑的原因 - 想象了2个解决方法。
<强>为什么:强>
单步执行渲染代码,剪辑rect被限制为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个图像并将它们组合起来(我仍然需要弄清楚但我觉得这是更好的修复)