c++qtqt5renderingqimage

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

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