Displaying and sizing a grayscale from a QImage in Qt

11,743

Solution 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.

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

Solution 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

Share:
11,743
Derek
Author by

Derek

#SOreadytohelp

Updated on June 13, 2022

Comments

  • Derek
    Derek almost 2 years

    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