Derek
Derek

Reputation: 11915

How to display this data buffer in a QImage

I have an image I am trying to display in a QImage.

This is the snippet of code that populates the rows*cols image:

    rgbMapped[row][col * 3] = red;

    rgbMapped[row][col * 3 + 1] = green;

    rgbMapped[row][col * 3 + 2] = blue;

As you can see, my data buffer is "rows-high" and is "cols*3 wide"

rgbMapped is an unsigned char** array. So back in my QT code I have the following:

QImage *qi = new QImage(getWidth(), getHeight(), QImage::Format_RGB888);

for (int h = 0; h< getHeight(); h++){
    memcpy(qi->scanLine(h), rgbMapped[h], getWidth()*3);
}
QPixmap p(QPixmap::fromImage(*qi,Qt::ColorOnly));

if(scene.items().contains(item)){
    scene.removeItem(item);
}
item = new ImagePixmapItem(p);
scene.addItem(item);
ui->graphicsView->setScene(&scene);
ui->graphicsView->show();

ImagePixMapItem is a QGraphicsPixmapItem that I have created to allow me to intercept some mouse events, but I dindt do anyhting with any of the paint functions or anything.

When I run this code, my return comes back as an image that looks like my image, except there are three copies, one with a green tint, one looking yellow-ish and one with a noticeable purple tint.

It seems like maybe it would be the correct image if these three pieces of data were..overlayed on each other?

Upvotes: 0

Views: 2004

Answers (2)

rep_movsd
rep_movsd

Reputation: 6895

Are you accounting for stride? Each scanline must begin on a 4 byte boundary. Also it may not be a packed pixel format, so each pixel is 4 bytes not 3

Upvotes: 1

Fivos Vilanakis
Fivos Vilanakis

Reputation: 1500

Just an assumption, but from the (wrong) colors you mentioned, I suspect the problem could be with your allocation/initialization code regarding the char **rgbMapped variable. Could you please post this code?

I will try to write bellow a possibly correct(?) initialization code just to give you a hint which may help (I haven't compile the code, therefore I apologize for any syntax errors). I use malloc() but you can also use the new() operator.

// allocate a single buffer for all image pixels
unsigned char *imgbuf = malloc(3 * getWidth() * getHeight());

// allocate row pointers
unsigned char **rgbMapped = malloc(getHeight() * sizeof (unsigned char *)); 

// Initialize row pointers
for (int h=0; h < getHeight(); h++)
{
  *rgbMapped[h] = &imgbuf[h * 3 * getWidth()];
}

// ... do your processing

// Free the image buffer & row pointers
free(imgbuf);
imgbuf = NULL;
free(rgbMapped);
rgbMapped = NULL;

The important part is the initialization of row pointers (did you forget the *3?). Just my 2c.

Upvotes: 1

Related Questions