【问题标题】:Can I add one QImage to another without using raster painting ?我可以在不使用光栅绘画的情况下将一个 QImage 添加到另一个吗?
【发布时间】:2016-03-14 13:58:01
【问题描述】:

我的项目要求是我可以创建一个宽度最大为 36000 像素(高度小得多)的图像。
(图片来自QGraphicsScene)。

我遇到了一个限制:QPainter 限制了光栅绘画的设备大小:

void QRasterPaintEnginePrivate::systemStateChanged()
{
    deviceRectUnclipped = QRect(0, 0,
            qMin(QT_RASTER_COORD_LIMIT, device->width()),
            qMin(QT_RASTER_COORD_LIMIT, device->height()));
    ....
}

// This limitations comes from qgrayraster.c. Any higher and
// rasterization of shapes will produce incorrect results.
const int QT_RASTER_COORD_LIMIT = 32767;

(我的故障排除尝试...Rendering a large QGraphicsScene on a QImage clips it off

所以...我想,我可以创建 2 个图像然后添加它们吗? (一个在对方的末尾)

if(wOutput > 32767)
{
    QImage image1 = QImage(32767, hOutput, QImage::Format_Mono);
    image1.fill(QColor(Qt::white).rgb());
    QRectF source(0, 0, 32767, hOutput);
    QRectF target(0, 0, 32767, hOutput);
    QPainter painter;
    painter.begin(&image1);
    outputScene->render(&painter, target, source);
    painter.end();

    QImage image2 = QImage(wOutput - 32767, hOutput, QImage::Format_Mono);
    image2.fill(QColor(Qt::white).rgb());
    source = QRectF(32767, 0, wOutput - 32767, hOutput);
    target = QRectF(0, 0, wOutput - 32767, hOutput);    
    painter.begin(&image2);
    outputScene->render(&painter, target, source);
    painter.end();

    // now create a combination, add image2 at the end of image1
    QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
    painter.begin(&image);
    painter.drawImage(0, 0, image1);
    painter.drawImage(32767, hOutput, image2);
    painter.end();
}
else
{
    // just create the image
}

看起来很合乎逻辑...但输出未显示image2。显然...我使用的是相同的光栅绘画...具有相同的限制!

还有什么其他方法可以在另一张图片的末尾添加一张图片? (注意 - 我的“大”尺寸是“宽度”,所以我什至不认为我可以使用 scanline 更快地复制像素)

【问题讨论】:

  • 为什么不想使用扫描线来获取像素数据并复制呢?
  • @Fabio - 我可以 - 但如何

标签: qt qpainter qimage


【解决方案1】:

您可以使用QImage::scanLine 获取像素数据并进行复制。 但是QImage::Format_Mono 让它变得更复杂一些,因为您必须考虑像素数据的对齐方式(QImage::Format_Mono 每个像素有 1 位,因此一个字节有 8 个像素)。

我建议使用可被 8 整除的宽度(例如 32760)生成第一个图像,这样您就可以复制第二个图像的行而不用移位。

两个源图像中的颜色表也应该相同。

你可以这样做:

int w1 = 32760;
QImage image1 = QImage(w1, hOutput, QImage::Format_Mono);
//grab the first  image....
//....
int w2 = wOutput - w1;
QImage image2 = QImage(w2, hOutput, QImage::Format_Mono);
//grab the second image....
//....

int bytesPerLine1 = w1 / 8; //is divisible by 8
int bytesPerLine2 = ceil(float(w2) / 8.0f); //should be right :)
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
image.setColorTable(image1.colorTable());
for(int i = 0; i < hOutput; ++i)
{
    uchar* dstSL = image.scanLine(i);
    uchar* src1SL = image1.scanLine(i);
    memcpy(dstSL, src1SL, bytesPerLine1);
    uchar* src2SL = image2.scanLine(i);
    memcpy(&dstSL[bytesPerLine1], src2SL, bytesPerLine2);
}

我还建议阅读 QImage 文档:Pixel ManipulationQImage::Format

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多