Примененный в G-Basic Console дисплей оперирует 18- или 16-битным цветом. 18-битный цвет - по 6 бит на каждую компоненту RGB хранить неудобно. Поэтому для простых применений дисплей поддерживает работу с 16-битным цветом - на компоненту G отводится по прежнему 6 бит, а на компоненты R и B - по 5 бит. Коротко такой формат обозначается RGB565.
Соответственно, вся работа с изображениями и цветом в консоли идет в 16-битном формате. Как задание цвета для пера, так и хранение спрайтов в памяти консоли. Для легкой и быстрой работы с изображениями было принято решение хранить в файлах преобразованные к 16-битному цвету изображения.
Ниже - описание формата файла и утилиты конвертации изображений в такой файл.
В файле, кроме данных о цветах пикселей, необходимо сохранить еще и размер изображения - ширину и высоту.
Итого, формат файла очень простой:
2 байта - ширина изображения
2 байта - высота изображения
по 2 байта на каждый пиксель - цвета пикселей построчно, слева направо, сверху вниз.
Представление значений - 16-битное слово.
Фрагмент такого файла:
Первые 2 байта - ширина - 0x0032 = 50 пикселей
Вторые 2 байта - высота - 0x003C = 60 пикселей
Далее - 50 слов (100 байт) - цвета первой строки пикселей.
Далее вторая строка и т.д.
Следует иметь ввиду, что G-Basic не позволит загрузить и нарисовать изображение с размерами, большими чем размер примененного дисплея - 240х240 пикселей.
Так же, при загрузке изображений в память (в массив) следует учитывать объем доступной оперативной памяти - это 59000 байт за вычетом статических и временных переменных.
Объем доступной памяти ("кучи") виден при компиляции программы:
Доступную память используют все объявляемые массивы , а так же строки (которые по своей сути тоже одномерные массивы).
Программа для кодирования изображений.
Для конвертации изображений в понятный G-Basic-у формат написана простая программа.
Программа позволяет вставить из буфера любое изображение размером до 255х255 пикселей и сохранить это изображение в файл вышеописанного формата.
После вставки изображения становится доступной кнопка сохранения преобразованного изображения в файл, изображение появляется в области просмотра. Изображение в области просмотра можно увеличить соответствующими переключателями.
Программу можно взять тут.
Немножко о преобразованиях 24-битного цвета в 16-битный и обратно.[1]
Преобразование 24 битного цвета в 16-битный.
Самое простое преобразование - это сдвиг значения цвета вправо с потерей 2 или 3 бит значения:
r5 = r8 >> 3;
g6 = g8 >> 2;
b5 = b8 >> 3;
Это не всегда корректное, но самое простое и быстрое преобразование.
Правильная формула преобразования для канала с из формата X в Y выглядит следующим образом:
cY = cX * max(cY)/max(cX)
Причем это преобразование должно производиться в вещественных значениях с результирующим математическим округлением.
Но в любом случае такое преобразование - это преобразование с потерями, поскольку уменьшается глубина цвета.
Преобразование 16-битного цвета в 24-битный
Можно попробовать выполнить обратное преобразование простым сдвигом:
r8 = r5 << 3;
g8 = g6 << 2;
b8 = b5 << 3;
Но получится фигня. Следим за руками:
24-битный белый: (255, 255, 255) преобразовываем в 16-битный:
r5 = r8 >> 3 = 255 >> 3 = 31g6 = g8 >> 2 = 255 >> 2 = 63
b5 = b8 >> 3 = 255 >> 3 = 31
И преобразовываем обратно:
r8 = r5 << 3 = 31 << 3 = 248
g8 = g6 << 3 = 63 << 2 = 252
b8 = b5 << 3 = 31 << 3 = 248
Т.е. после вот такого преобразования "в лоб" мы получим не белый, а что то светло-светло-серое, да еще и с зеленым оттенком.
Что бы такого не было, можно воспользоваться приведенной выше формулой преобразования. Эта формула универсальна. Её минус - это вычисления с плавающей запятой, что может быть накладно по скорости.
Есть вариант табличного преобразования - у нас всего 32 значения для R и B-компонент и 64 значения для G-компоненты цвета:
Table5 = { 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123,
132, 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255};
Table6 = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61,
65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125,
130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190,
194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255};
r8 = Table5[r5];
g8 = Table6[g6];
b8 = Table5[b5];
Метод быстрый, простой, но требует 96 байт для массивов)) На современных МК это ну вообще не проблема.
Но если не хочется заморачиваться с массивом, можно при преобразовании копировать старшие биты в младшие после сдвига.
r8 = ( r5 << 3 ) | (r5 >> 2);
g8 = ( g6 << 2 ) | (g6 >> 4);
b8 = ( b5 << 3 ) | (b5 >> 2);
Этот способ при преобразовании RGB565 в RGB888 дает незначительную погрешность относительно математического преобразования. Способ тоже быстрый и не требует вычислений с плавающей запятой.
[1] tune it - Преобразование RGB888 <-> RGB565
Тарас
ОтветитьУдалитьJPEG на мк не приходилось декодировать? Пробовал 2 либы Elm Chan, так и не смог их запустить.
ОтветитьУдалитьне-а.... Не задавался данным вопросом
Удалить