Задать вопрос
@Dogrtt
Qt/Python разработчик

Как с помощью QT вывести на монитор 10-битное изображение?

Добрый день. Недавно появился снэпшот Qt 5.13, в котором у QImage стал доступен формат QImage::Format_Grayscale16. Около года назад, мне уже приходилось работать с QImage, но тогда речь шла только о 8-битах. Так как на работе есть 10-битный монитор, я решил попробовать создать и вывести на него градиент 1024x400, в котором каждый пиксель должен быть на тон светлее предыдущего (2^10=1024). Сформировав QByteArray следующим образом:
Генерация QByteArray
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;
}


Я попытался сформировать QImage так же, как делал это прежде:
Формирование 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;
}


Однако, результат был неожиданным, вместо градиента на 1024px, сформировалось целых четыре по 256px:
Результирующий градиент
5c4ee2c8c4afa451186511.png

Такое ощущение, что QImage сформировался только по четным байтам из QByteArray.
Что лежи в массиве

(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, <...>) и т.д.

Вопрос, как можно побороть подобное? Кто-нибудь уже работал с QImage::Format_Grayscale16?
  • Вопрос задан
  • 342 просмотра
Подписаться 2 Сложный 3 комментария
Решения вопроса 1
@fregate
Пишу, думаю
partA = static_cast<uint8_t>((color &0xFF00) >> 8); // == 0 всегда
partB = static_cast<uint8_t>(color &0x00FF); // 0..255

за 1024 точки partB 4 раза проходит от 0 до 255 - по-этому вы видите 4 градиента.
вы неправильно создаете его

16 бит grayscale - значит, значение тона меняется от 0..65535, вам необходимо "сжать" этот диапазон в 1024 точки то есть каждая точка в горизонтали должна заполняться как-то так:
for (ushort color = 0; color < 1024; color++)
      arr->append (color * 64);  // * 65536/1024

таким образом каждая точка будет увеличиваться на нужный шаг. если хотите сделать "челлендж" своему монитору, то вам нужно не весь ряд отобразить, а отобразить именно 10-20 тонов, тогда вам нужно "разжать" 10-20 тонов на 1024 точки - тут вы уже справитесь, я думаю.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы