Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: OKTA от Апреля 30, 2014, 16:40



Название: QImage from 8-bit Raw data
Отправлено: OKTA от Апреля 30, 2014, 16:40
Товарищи, подскажите, как лучше всего впихнуть в QImage картинку из сырых 8-битных данных (всмысле без заголовка какого-либо)?
Идея создавать QImage c форматом Indexed8 и затем задавать colortable на все возможные 8-битные цвета показалось мне какой-то диковатой  :-[


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Апреля 30, 2014, 17:10
Товарищи, подскажите, как лучше всего впихнуть в QImage картинку из сырых 8-битных данных (всмысле без заголовка какого-либо)?
Идея создавать QImage c форматом Indexed8 и затем задавать colortable на все возможные 8-битные цвета показалось мне какой-то диковатой  :-[
Что вы подразумеваете под 8-битными данными? Если это палитровай режим, где индекс цвета задается байтом, то палитра понадобится все равно. Если она не идет с данными, то вам придется самому ее формировать. Как минимум нужно будет задать цвета, индексы которых есть в данных.


Название: Re: QImage from 8-bit Raw data
Отправлено: xokc от Апреля 30, 2014, 17:18
Идея создавать QImage c форматом Indexed8 и затем задавать colortable на все возможные 8-битные цвета показалось мне какой-то диковатой  :-[
И в чем же её дикость? Вообще не представляю как можно это сделать по-другому.
Код
C++ (Qt)
QImage gray((const uchar *)bits.data(), width, bits.length() / width, QImage::Format_Indexed8);
QVector<QRgb> palette;
for (int i = 0; i < 255; ++i) palette.append(qGray(i, i, i);
gray.setColorTable(palette);
gray.save(file.fileName() + ".jpg");


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Апреля 30, 2014, 17:25
Часто проще сразу прописать в true color, т.е. создать Format_ARGB32 и заполнить. Ничего что RGB одинаковые, сидеть с Indexed8 неудобно.

ТС любит загадки, вот хорошая: имедж хранит 4 байта на точку, но значения по R, G, B - флоты. Как он устроен?  :)


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Апреля 30, 2014, 18:13
Вообще не представляю как можно это сделать по-другому.

255 тоже должно быть включено в палитру:
Код
C++ (Qt)
for (int i = 0; i < 255; ++i) palette.append(qGray(i, i, i);
 


Название: Re: QImage from 8-bit Raw data
Отправлено: xokc от Мая 01, 2014, 17:51
255 тоже должно быть включено в палитру:
Согласен, в общем случае, несомненно - да. Мой случай был несколько "кастрированным", у меня в исходных данных не было цвета с индексом 255. Но здесь, конечно, нужно цикл крутить до 255 включительно.


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Мая 01, 2014, 18:03
Согласен, в общем случае, несомненно - да. Мой случай был несколько "кастрированным", у меня в исходных данных не было цвета с индексом 255. Но здесь, конечно, нужно цикл крутить до 255 включительно.
Или сделать наоборот, пробежаться по данным и заполнить в палитре только те цвета, индексы которых присутствуют. Может там все изображение состоит из каких нибудь пяти цветов.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 05, 2014, 09:55
Да, именно индексы содержатся.  Не могу понять, почему QImage не поддерживает формат Indexed8  ??? Это сделано ради экономии места или чего? Хотел как раз избавить себя от создания таблицы цветов вручную, потому и спросил о других вариантах решения, если они вообще существуют.
как понимаю, с помощью этого создается таблица для "grayscale"
Код:
for (int i = 0; i < 255; ++i) palette.append(qGray(i, i, i);
А если не grayscale, то как надо создавать таблицу цветов?  :o Хотя видимо выдернуть сначала все используемые индексы и по ним составлять таблицу будет куда удобнее на первый взгляд.

По загадке подумаю)


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 05, 2014, 10:42
А если не grayscale, то как надо создавать таблицу цветов?  :o

Напр пользователь выбирает какие-то определенные цвета (из UI) и ими рисует. В результате имедж может быть записан 1 байт на точку (и даже меньше). Т.е. единственный резон - экономия памяти (что не компенсирует хлопот). Поэтому палитра уже лет 20 (если не больше) "дань истории".


Название: Re: QImage from 8-bit Raw data
Отправлено: xokc от Мая 06, 2014, 10:17
Не могу понять, почему QImage не поддерживает формат Indexed8  ???
Видимо у нас какие-то разные представления о формате Indexed8. В этом формате предполагается, что:
1. изображение содержит не более 256 цветов
2. все значения элементов данных в изображении есть не цвет как таковой, а индекс в массиве цветов (палитре)
3. соответственно системе для рисования этого изображения нужно получить от пользователя не только элементы данных, но и палитру. Без неё непонятно что именно рисовать.
Все эти требования QImage поддерживает в полном объеме.
Хотя видимо выдернуть сначала все используемые индексы и по ним составлять таблицу будет куда удобнее на первый взгляд.
Я правильно понимаю, что Вы предполагаете, что существует некая стандартная системная предопределенная палитра из 256 цветов, типа VGA 256?
Это заблуждение. Никто, кроме пользователя не сможет сможет сказать какой именно цвет должен соответствовать каждому их значений индекса. Именно поэтому формирование палитры возлагается на пользователя.
А если не grayscale, то как надо создавать таблицу цветов?  :o
Можно так for (int i = 0; i < 256; ++i) palette.append(0) - если хотите всегда черный "квадрат" видеть, можно так palette.append(qRgb(0, 0, i)) - если bluescale нужен. Кроме Вас этого всё равно никто знать не может.


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 06, 2014, 11:44
Я правильно понимаю, что Вы предполагаете, что существует некая стандартная системная предопределенная палитра из 256 цветов, типа VGA 256?
Это заблуждение. Никто, кроме пользователя не сможет сможет сказать какой именно цвет должен соответствовать каждому их значений индекса. Именно поэтому формирование палитры возлагается на пользователя.
Существуют, есть даже форматы файлов для хранения палитр. Можно наблюдать напр в старых редакторах ресурсов на Mac. Но, повторюсь, интерес к палитре давно угас.


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Мая 06, 2014, 11:55
Существуют, есть даже форматы файлов для хранения палитр.
xokc пишет про другое.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 12:23
Да, с этим всем я согласен. Но что делать, если я получаю изображение без таблицы цветов? Должна же быть какая-то стандартная схема? Или же qRgb(i,i,i) в цикле как раз эту стандартную схему и дает?
Я может что-то путаю конечно и ошибка где-то у меня, но ситуация следующая.
Я получаю 8-битное изображение без палитры цветов. Работаю с ним через QImage, задавая размеры изображения, количеств байт в строке и формат Indexed8. После этого, независимо от того, задам я таблицу цветов или не задам, я получаю видимое изображение, хоть и цвета могут быть искаженными (при чем чаще всего случайно искажены). И в итоге не могу понять, какую подсунуть таблицу цветов, чтобы получить нормальное ожидаемое изображение без искажений  :-\ А может 8-битное изображение не использовать палитру или если 8-битное, то обязательно используется палитра?


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 12:24
Цитировать
ТС любит загадки, вот хорошая: имедж хранит 4 байта на точку, но значения по R, G, B - флоты. Как он устроен?  Улыбающийся
Igors, а что имелось ввиду под словом "флот"?


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Мая 06, 2014, 12:28
И в итоге не могу понять, какую подсунуть таблицу цветов, чтобы получить нормальное ожидаемое изображение без искажений  :-\
Попробуйте задать палитру как показал xokc в третьем сообщении.

Igors, а что имелось ввиду под словом "флот"?
float


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 12:40
А получается тоже самое - хоть через qGray, хоть через qRgb.
Тоже самое в плане искаженные цвета.


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Мая 06, 2014, 12:58
Вы должны получить "серое" изображение. Все цвета это оттенки серого. Правильно?
Если в картинке вы ожидаете другие цвета, то вам придется эту палитру формировать самому. Смотреть на картинку на каждую точку, брать ее индекс в палитре и устанавливать нужные значения RGB.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 13:07
В этом-то и вся странность - задаю палитру через qGray как и советовал xokc, а в изображении появляются другие цвета - желтый, красный и т.д.


Название: Re: QImage from 8-bit Raw data
Отправлено: Old от Мая 06, 2014, 13:14
В этом-то и вся странность - задаю палитру через qGray как и советовал xokc, а в изображении появляются другие цвета - желтый, красный и т.д.
А палитру точно устанавливаете?
Покажите ваш код.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 13:20
Код:
QImage image(reinterpret_cast<unsigned char*>(imageSrc->data()),
                    params.pixels_per_line, params.lines,
                    params.bytes_per_line, QImage::Format_Indexed8);

    QVector<QRgb> colors;
    for(int i = 0; i < 255; ++i)
        colors.append(qGray(i,i,i));

    image.setColorTable(colors);
    image.save("testImage.tiff");
Как понимаю, этого должно быть достаточно.


Название: Re: QImage from 8-bit Raw data
Отправлено: xokc от Мая 06, 2014, 13:26
В этом-то и вся странность - задаю палитру через qGray как и советовал xokc, а в изображении появляются другие цвета - желтый, красный и т.д.
Этого не может быть, потому что не может быть никогда. :) Давайте код сюда. Видимо, что то Вы не так делаете либо когда палитру устанавливаете, либо когда получившийся QImage рисуете или сохраняете. Как вариант - выложите сюда тот самый исходный QByteArray, посмотрим что с ним не так. Можно ещё после setColorTable сделать bmp.save("c:/test.png") и посмотреть, что именно сохранится.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 14:19
Так, ну вот файлики в аттаче. Изображение, которое получается при использовании кода, который я выше привел и исходное изображение - просто записанный в файл QByteArray.


Название: Re: QImage from 8-bit Raw data
Отправлено: xokc от Мая 06, 2014, 14:36
    for(int i = 0; i < 255; ++i)
        colors.append(qGray(i,i,i));
Вы пропустили наш диалог с Old в начале топика относительно того, что цикл надо крутить до 256, а не до 255. У Вас в картинке всего два цвета - 0 и 255, а в палитре цвета 255 - нет, точнее он заполняется случайным цветом - поэтому и появляются "всякие разные цвета".


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 14:38
Ой, опечатка. Но от нее ничего не меняется к сожалению :-[


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 06, 2014, 14:40
О, кажется нашел косяк - ситуация исправляется, если ставить QRgb вместо QGray  :o

Ну все, пока вопросов нет, всем спасибо!  ;)


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 07, 2014, 08:34
Igors, а что имелось ввиду под словом "флот"?
float
Да


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 07, 2014, 11:24
Странная загадка)
Можно сделать мне кажется лишь используя таблицу цветов, чтобы изображение рисовалось, используя индекс по каждому каналу отдельно, а не общий цвет. Но если значения флоаты, то все не поместится в таблицу, если 4 байта на пиксель  ???


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 07, 2014, 11:40
Странная загадка)
Можно сделать мне кажется лишь используя таблицу цветов, чтобы изображение рисовалось, используя индекс по каждому каналу отдельно, а не общий цвет. Но если значения флоаты, то все не поместится в таблицу, если 4 байта на пиксель  ???
Этот формат довольно популярен и используется уже минимум лет 10. Да, хранится 4 байта, но используются 3 float (ну разумеется с какой-то потерей точности). Остряки часто называют это "ельфа"  :)  


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 07, 2014, 12:01
Чего-то я не нашел этого ельфа ;D Дайте ссылку пожалуйста)
Из похожих нашел openEXR, но там без альфа-канала 6 байт на точку получается для чисел половинной точности.


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 07, 2014, 12:08
Чего-то я не нашел этого ельфа ;D Дайте ссылку пожалуйста)
http://en.wikipedia.org/wiki/RGBE_image_format (http://en.wikipedia.org/wiki/RGBE_image_format)

Из похожих нашел openEXR, но там без альфа-канала 6 байт на точку получается для чисел половинной точности.
Да, это основная альтернатива. Кстати "числа половинной точности" там не так уж просты.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 07, 2014, 12:18
Да, классно придумано с общей экспонентой!!
Условие загадки меня смутило и я исходил из того, что float - обычный float одинарной точности, а не просто число с плавающей запятой.  :)


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 07, 2014, 12:21
Еще загадка: ну а зачем нужны float если современные мониторы все равно умеют показывать только (0..255) на канал?


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 07, 2014, 12:55
Да просто при обработке таких изображений будет меньше артефактов и искажений я думаю.
А насчет мониторов - человеческий глаз и так не может увидеть больше 24bit  :)


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 07, 2014, 13:52
Да просто при обработке таких изображений будет меньше артефактов и искажений я думаю.
А насчет мониторов - человеческий глаз и так не может увидеть больше 24bit  :)
Вижу нет интереса, ладно, пример: имеем картинку на которой есть солнце (яркое пятно). Теперь мы всего-навсего хотим ее заблюрить (размыть). В "обычном" формате солнце у нас быстро "растворится" в небе. А в HDRI  солнце будет расти и расти.


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 07, 2014, 14:10
Ну так это и есть тоже самое, что и искажение при обработке. Грубо говоря, имея больше информации о цвете в одном пикселе, мы можем производить больше операций с меньше потерей качества. А в статике мы будем видеть одно и тоже изображение что с плавающими числами, что с фиксированными.


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 08, 2014, 10:14
Ну так это и есть тоже самое, что и искажение при обработке. Грубо говоря, имея больше информации о цвете в одном пикселе, мы можем производить больше операций с меньше потерей качества.
Ну вообще-то идея в другом, но т.к. Вам уже все ясно, то ладно  :)


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 12, 2014, 09:15
Так в чем-же идея?)


Название: Re: QImage from 8-bit Raw data
Отправлено: Igors от Мая 12, 2014, 11:31
Так в чем-же идея?)
Если просто нужна бОльшая точность, то есть форматы 2 байта (unsigned short) на канал. Напр tiff это поддерживает. Но при этом диапазон тот же [0..1], просто значений (0..65536) вместо (0..255).

А основное применение флотов - IBL (image based lighting) и "tone mapping". Рассказывать долго, интересно - почитайте 


Название: Re: QImage from 8-bit Raw data
Отправлено: OKTA от Мая 12, 2014, 13:05
Почитал, спасибо!  ;)