在QImage上渲染大型QGraphicsScene会将其剪切掉

时间:2016-03-03 20:20:45

标签: qt rendering qgraphicsscene qpainter

我正在创建一些渲染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像素,其余为黄色,没有红色矩形。

enter image description here

#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

中运行它

1 个答案:

答案 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个图像并将它们组合起来(我仍然需要弄清楚但我觉得这是更好的修复)