大QImage的问题

问题描述 投票:0回答:4

我对 C++/Qt 相当陌生,我正在尝试使用 Visual Studio C++ 和 Qt (4.8.3) 创建一个应用程序。该应用程序使用 QGraphicsView 显示图像,我需要在像素级别更改图像。

基本代码是(简化):

QImage* img = new QImage(img_width,img_height,QImage::Format_RGB32);
while(do_some_stuff) {
  img->setPixel(x,y,color);
}
QGraphicsPixmapItem* pm = new QGraphicsPixmapItem(QPixmap::fromImage(*img));
QGraphicsScene* sc = new QGraphicsScene;
sc->setSceneRect(0,0,img->width(),img->height());
sc->addItem(pm);
ui.graphicsView->setScene(sc);

这对于高达 12000x6000 像素左右的图像效果很好。超出这个尺寸就会发生奇怪的事情。例如,当我设置

img_width=16000
img_height=8000
时,
img = new QImage(...)
行返回空图像。图像数据应约为 512,000,000 字节,因此即使在 32 位系统上也不应太大。另外,我的机器(Win 7 64位,8 GB RAM)应该能够保存数据。

我也尝试过这个版本:

uchar* imgbuf = (uchar*) malloc(img_width*img_height*4);
QImage* img = new QImage(imgbuf,img_width,img_height,QImage::Format_RGB32);

一开始,这很有效。 img 指针有效,并且调用

img->width()
例如会返回正确的图像宽度(而不是 0,以防图像指针为空)。 但是当我调用
img->setPixel()
时,指针就变成空并且
img->width()
返回 0。

那么我做错了什么?或者有没有更好的方法在像素级别上修改大图像?

问候, 大卫

c++ qt qgraphicsscene qimage qpixmap
4个回答
4
投票

QImage 支持最大 32768x32768 像素的图像(短符号)。这是根据以下条件得出的:宽度 * 高度 * 颜色深度 < INT_MAX (4 billion) -> 32768 * 32768 * 4 = 40 亿。第二个条件当然是malloc能够分配所请求的内存。

如果您确实需要更大的图像,则必须使用另一个包装器或分成多个 QImage。


2
投票

我找到了问题所在。我只是忘记将

/LARGEADDRESSAWARE
标志添加到链接器选项中。

我也非常感谢 Stephen Chu 使用 scanLine() 提示的回答。首先,它节省了一些内存,其次,它确实快了很多。

现在我可以安全地创建高达 32000x16000 像素的图像,这是我想要的目标。


1
投票

您的第二种方法是正确的方法。您遇到的问题是,当您调用

setPixel()
时,
QImage
会复制您提供的外部缓冲区并耗尽内存。

尝试直接在提供的缓冲区中更改像素值。您可以使用

scanLine()
来获取指向行缓冲区的指针。无论如何我不会使用
setPixel()
,因为它真的很慢。


0
投票

从 Qt 6 开始,您只需调用:

  QImageReader::setAllocationLimit(4096);

在此处查看相关文档。在上面的示例中,我将限制设置为 4GB。可以通过设置环境变量来覆盖该值

QT_IMAGEIO_MAXALLOC

© www.soinside.com 2019 - 2024. All rights reserved.