我是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.
那么我做错了什么?或者是否有更好的方法在像素级别修改大图像?
此致 大卫
答案 0 :(得分:4)
QImage支持最多32768x32768像素图像(签名短)。这遵循以下条件:width * height * colordepth< INT_MAX(40亿) - > 32768 * 32768 * 4 = 40亿。第二个条件当然是malloc能够分配所请求的内存。
如果你真的需要更大的图像,你将不得不使用另一个包装或分成多个QImage。
答案 1 :(得分:2)
我追查了这个问题。我忘了将/LARGEADDRESSAWARE
标志添加到链接器选项中。
我也很欣赏Stephen Chu对scanLine()提示的回答。首先它节省了一些内存,其次它真的要快得多。
现在我可以安全地创建高达32000x16000像素的图像,这是我想要的目标。
答案 2 :(得分:1)
你的第二种方法是正确的方法。您遇到的问题是,当您致电setPixel()
时,QImage
会复制您提供的外部缓冲区并为此耗尽内存。
尝试直接在提供的缓冲区中更改像素值。您可以使用scanLine()
获取指向行缓冲区的指针。我不会使用setPixel()
,因为它真的很慢。