在 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 个图像并将它们组合(我仍然需要弄清楚,但我认为这是更好的解决方法)