5

I'm pretty new to C++/Qt and I'm trying to create an application with Visual Studio C++ and Qt (4.8.3). The application displays images using a QGraphicsView, I need to change the images at pixel level.

The basic code is (simplified):

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);

This works well for images up to around 12000x6000 pixel. The weird thing happens beyond this size. When I set img_width=16000 and img_height=8000, for example, the line img = new QImage(...) returns a null image. The image data should be around 512,000,000 bytes, so it shouldn't be too large, even on a 32 bit system. Also, my machine (Win 7 64bit, 8 GB RAM) should be capable of holding the data.

I've also tried this version:

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

At first, this works. The img pointer is valid and calling img->width() for example returns the correct image width (instead of 0, in case the image pointer is null). But as soon as I call img->setPixel(), the pointer becomes null and img->width() returns 0.

So what am I doing wrong? Or is there a better way of modifying large images on pixel level?

Regards, David

4

3 回答 3

4

QImage supports a maximum of 32768x32768 px images (signed short). This follows from the condition: width * height * colordepth < INT_MAX (4 billion) -> 32768 * 32768 * 4 = 4 billion. The second condition is of course that malloc is able to allocate the requested memory.

If you really need bigger images you will have to use another wrapper or split into multiple QImage's.

于 2012-11-26T23:38:05.827 回答
2

我追查了问题。我只是忘记将/LARGEADDRESSAWARE标志添加到链接器选项中。

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

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

于 2012-11-28T22:38:19.667 回答
1

您的第二种方法是正确的方法。您遇到的问题是当您调用 时setPixel()QImage会复制您提供的外部缓冲区并用完它的内存。

尝试直接在提供的缓冲区中更改像素值。您可以使用scanLine()来获取指向行缓冲区的指针。反正我不会使用setPixel(),因为它真的很慢。

于 2012-11-27T19:59:21.453 回答