P
P
Philip Bondarev2019-01-28 14:18:51
Qt
Philip Bondarev, 2019-01-28 14:18:51

How to use QT to display a 10-bit image on the monitor?

Good afternoon. The Qt 5.13 snapshot was recently released, making the QImage ::Format_Grayscale16 format available to QImage . About a year ago, I already had to work with QImage , but then it was only about 8-bits. Since I have a 10-bit monitor at work, I decided to try to create and display a 1024x400 gradient on it, in which each pixel should be one tone lighter than the previous one (2^10=1024). By forming a QByteArray like this:

QByteArray generation
QByteArray *ArrayGenerator::gen10bitArr()
{
    QByteArray *arr = new QByteArray();
    uint8_t partA;
    uint8_t partB;
    for (int row = 0; row < 400; row++) {
        for (uint16_t color = 0; color < 1024; color++) {
                partA = static_cast<uint8_t>((color &0xFF00) >> 8);
                partB = static_cast<uint8_t>(color &0x00FF);
                arr->append (partA);
                arr->append (partB);
        }
    }
    return arr;
}


I tried to form the QImage the same way I did before:
Forming a QImage
QImage &MainWindow::gen10bitImg(QByteArray*data, int width, int height)
{
    QImage * img = new QImage((uchar*)data->data (),
                              width, height, 2048, QImage::Format_Grayscale16);
    img->save ("image.png");
    return *img;
}


However, the result was unexpected, instead of a 1024px gradient, four 256px gradients formed:
Resulting Gradient
5c4ee2c8c4afa451186511.png

It seems that QImage was formed only by even bytes from QByteArray .
What lies in the array

(0, 0, 0, 1, 0, 2, 0, 3, <...>, 0, 255, 1, 0, 1, 1, 1, 2, 1, 3, <...>, 1 , 255, 2, 0, 2, 1, 2, 2, 2, 3, <...>, 2, 255, 3, 0, <...>), etc.

The question is, how can this be overcome? Has anyone already worked with QImage::Format_Grayscale16 ?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton F, 2019-02-07
@Dogrtt

partA = static_cast<uint8_t>((color &0xFF00) >> 8); // == 0 всегда
partB = static_cast<uint8_t>(color &0x00FF); // 0..255

in 1024 points partB goes from 0 to 255 4 times - so you see 4 gradients.
you create it incorrectly
16 bit grayscale - it means that the tone value changes from 0..65535, you need to "compress" this range into 1024 points, that is, each point in the horizontal should be filled something like this:
for (ushort color = 0; color < 1024; color++)
      arr->append (color * 64);  // * 65536/1024

thus each point will increase by the desired step. if you want to make a "challenge" to your monitor, then you do not need to display the entire row, but display exactly 10-20 tones, then you need to "unclench" 10-20 tones into 1024 points - then you can do it, I think.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question