'QImage 16 bit grayscale with QQuickPaintedItem

I have unsigned 16 bit image data that I displayed by subclassing QQuickPaintedItem in Qt 5.12.3. I used QImage with Format_RGB32 and scaled the data from [0, 16383] to [0, 255] and set that as the color value for all three R,G,B. Now, I am using Qt 5.15.2 which has a QImage FORMAT_GrayScale16 that I'd like to use but for some reason the image is displayed incorrectly. The code I used to convert my unsigned 16 bit image data to QImage for both formats is shown below. The QQuickPaintedItem is a basic subclassing with drawImage(window(), my_qimage); that I pass the QImage as returned from the code below. Why is the new format not displaying correctly?

Format_RGB32 method

QImage image(image_dim, QImage::Format_RGB32);
unsigned int pixel = 0;
for (uint16_t row = 0; row < nrow; row++) {
    uint *scanLine = reinterpret_cast<uint *>(image.scanLine(row));
    for (uint16_t col = 0; col < ncols; col++) {
        uint16_t value = xray_image.data()[pixel++]; // Get each pixel
        unsigned short color_value = uint16_t((float(value) / 16383) * 255.0f); // scale [0, 255]
        *scanLine++ = qRgb(int(color_value), int(color_value), int(color_value));
    }
}
return image;

Format_RGB32

Format_Grayscale16 method

QImage image(image_dim, QImage::Format_Grayscale16);
unsigned int pixel = 0;
for (uint16_t row = 0; row < nrow; row++) {
    // **EDIT WRONG:** uint *scanLine = reinterpret_cast<uint *>(image.scanLine(row));
    uint16_t *scanLine = reinterpret_cast<uint16_t *>(image.scanLine(row));
    for (uint16_t col = 0; col < ncols; col++) {
        *scanLine++ = xray_image.data()[pixel++]; // Get each pixel
    }
}
return image;

Format_Grayscale16



Solution 1:[1]

This worked for me (below is just fragments):

class Widget : public QWidget
{
private:
    QImage m_image;
    QImage m_newImage;
    QGraphicsScene *m_scene;
    QPixmap m_pixmap;
};
...
m_image.load("your/file/path/here");
m_newImage = m_image.convertToFormat(QImage::Format_Grayscale8);

m_pixmap.convertFromImage(m_newImage);
m_scene = new QGraphicsScene(this);
m_scene->addPixmap(m_pixmap);
m_scene->setSceneRect(m_pixmap.rect());

ui->graphicsView->setScene(m_scene);

Based on your OP, you probably want to render it differently. graphicsView is just a QGraphicsView defined in design mode.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mzimmers