Displaying and sizing a grayscale from a QImage in

2019-07-10 04:45发布

问题:

I have been able to display an image in a label in Qt using something like the following:

transformPixels(0,0,1,imheight,imwidth,1);//sets unsigned char** imageData

unsigned char* fullCharArray = new unsigned char[imheight * imwidth];
     for (int i = 0 ; i < imheight ; i++)
         for (int j = 0 ; j < imwidth ; j++)
                fullCharArray[(i*imwidth)+j] = imageData[i][j];

QImage *qi = new QImage(fullCharArray, imwidth, imheight, QImage::Format_RGB32);

ui->viewLabel->setPixmap(QPixmap::fromImage(*qi,Qt::AutoColor));

So fullCharArray is an array of unsigned chars that have been mapped from the 2D array imageData, in other words, it is imheight * imwidth bytes.

The problem is, it seems like only a portion of my image is showing in the label. The image is very large. I would like to display the full image, scaled down to fit in the label, with the aspect ratio preserved.

Also, that QImage format was the only one I could find that seemed to give me a close representation of the image I am wanting to display, is that what I should expect? I am only using one byte per pixel (unsigned char - values from 0 to 255), and it seems liek RGB32 doesnt make much sense for that data type, but none of the other ones displayed anything remotely correct

edit: Following dan gallaghers advice, I implemented this code:

QImage *qi = new QImage(fullCharArray, imwidth, imheight, QImage::Format_RGB32);
int labelWidth = ui->viewLabel->width();
int labelHeight = ui->viewLabel->height();

QImage small = qi->scaled(labelWidth, labelHeight,Qt::KeepAspectRatio);
ui->viewLabel->setPixmap(QPixmap::fromImage(small,Qt::AutoColor));

But this causes my program to "unexpectedly finish" with code 0

回答1:

QImage has a scaled member. So you want to change your setPixmap call to something like:

QImage small = qi->scaled(labelWidth, labelHeight, Qt::KeepAspectRatio);
ui->viewLabel->setPixmap(QPixmap::fromImage(small, Qt::AutoColor);

Note that scaled does not modify the original image qi; it returns a new QImage that is a scaled copy of the original.

Re-Edit:

To convert from 1-byte grayscale to 4-byte RGB grayscale:

 QImage qi = new QImage(imwidth, imheight, QImage::Format_RGB32);
 for (int i = 0; i < imheight; i++)
 {
     for (int j = 0; j < imwidth; j++)
     {
         qi->setPixel(i, j, QRgb(imageData[i][j], imageData[i][j], imageData[i][j]));
     }
 }

Then scale qi and use the scaled copy as the pixmap for viewLabel.



回答2:

Qt doesn't support grayscale image construction directly. You need to use 8-bit indexed color image:

QImage * qi = new QImage(imageData, imwidth, imheight, QImage::Format_Indexed8);
for(int i=0;i<256;++i) {
    qi->setColor(i, qRgb(i,i,i));
}


回答3:

I've also faced similar problem - QImage::scaled returned black images. The quick work-around which worked in my case was to convert QImage to QPixmap, scale and convert back then. Like this:

QImage resultImg = QPixmap::fromImage(image)
  .scaled( 400, 400, Qt::KeepAspectRatio )
  .toImage();

where "image" is the original image. I was not aware of format-problem, before reading this thread - but indeed, my images are 1-Bit black-white.

Regards, Valentin Heinitz



标签: c++ qt qt4