Перейти к содержанию
    

Сжать битовое представление больших текстовых символов

На ЖКИ нужно написать большие цифры, размером, например, 48 х 30 пикселей. Многие байты в символах повторяются, и биты в байтах идут группами.
Какой алгоритм сжатия символов в шрифте здесь можно применить, попроще?

И если символы буду занимать память разного размера, значит, обращаться к ним нужно через массив указателей.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, AlexRayne сказал:

А какой там принцип сжатия? Что-то с наскоку не откопал.
Например. Для одной строки растра символа задаётся начальный бит - 0 или 1, затем количество идущих подряд нулей или единиц, затем количество идущих подряд единиц или нулей, и т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, ViKo сказал:

На ЖКИ нужно написать большие цифры, размером, например, 48 х 30 пикселей. Многие байты в символах повторяются, и биты в байтах идут группами.
Какой алгоритм сжатия символов в шрифте здесь можно применить, попроще?

И если символы буду занимать память разного размера, значит, обращаться к ним нужно через массив указателей.  

10 цифр, 6*30*10 = 1800 байтов. Вряд ли вы сможете сэкономить столько, чтобы отбить затраты кода на обработку сжатия :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, ViKo сказал:

Какой алгоритм сжатия символов в шрифте здесь можно применить, попроще?

Если не заморачиваться с битами, то самое простое Кодирование длин серий (англ. run-length encoding, RLE)
 

2 часа назад, ViKo сказал:

И если символы буду занимать память разного размера, значит, обращаться к ним нужно через массив указателей. 

Компактней будет таблица длин символов в начале фонта и вычисление смещений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

48 x 4 x 10 = 1920
Потому и предполагаю примитивный алгоритм.

Кстати, да, если хранить символы боком, то там более длинные повторяющиеся последовательности.

 

Закодировать каждую строку символа (4 байта, в моём случае) одним байтом. Или столбец. 256 комбинаций с запасом хватит на все варианты начертания. Только таблица кодировки памяти потребует.

Ага. Собирать символы из примитивов - строк или столбцов. Или из кубиков. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Закодировать кубики 4 x 4 одним байтом. Хватит одного байта, наверное? Тогда на символ потребуется 96 кубиков вместо 192 байтов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если цифры "красивые" - унифицировать кривые, цифра сперва отрисовывается грубо, "квардатми-прямоугольниками", затем на нее дорисовываются изгибы (возможно, 4 шт, или вообще 1 в режиме зеркало/переворот). Напр. шрифт 5*8 масштабировать до требуемого, затем добавить стандартные кривые.

Видел давно калькулятор с "красивыми" цифрами, с закруглениями. Не графический, сегментами отображало достаточно хорошо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 минут назад, ViKo сказал:

Закодировать каждую строку символа (4 байта, в моём случае) одним байтом. Или столбец. 256 комбинаций с запасом хватит на все варианты начертания. Только таблица кодировки памяти потребует.:biggrin:

"Строка символа" - это как я понимаю - строка пикселей по ширине равная ширине символа?

Если так, то можно:

1. Подсчитать сколько всего таких 4-х-байтовых строк пикселей есть во всём шрифте (будет == число_символов_в_шрифте * число_строк_пикселей_в_символе (или высота символа по X)).

2. Подсчитать сколько из них уникальных (вычтя все повторяющиеся).

3. Составить таблицу (M) из уникальных строк пикселей.

4. Каждый символ описать не как массив строк пикселей, а как массив индексов таблицы M.

В зависимости от того, каков % уникальных строк пикселей, может получиться экономия. А может и нет. В любом случае - алгоритм выборки символа будет простой и быстрый.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 минуту назад, ViKo сказал:

Закодировать кубики 4 x 4 одним байтом. Хватит одного байта, наверное? Тогда на символ потребуется 96 кубиков вместо 192 байтов.

Не забывайте, что при подстановочном сжатии вам все равно словарь хранить нужно (те самые кубики).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или другой алгоритм (будет эффективен если символы действительно большие с толстыми линиями):

1. Записать каждую строку пикселей как последовательность: количество сплошных 0-й, количество сплошных 1-ц, количество сплошных 0-й, количество сплошных 1-ц, ...

2. Запаковать получившуюся строку в одно слово (16 бит).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, jcxz сказал:

Или другой алгоритм (будет эффективен если символы действительно большие с толстыми линиями):

1. Записать каждую строку пикселей как последовательность: количество сплошных 0-й, количество сплошных 1-ц, количество сплошных 0-й, количество сплошных 1-ц, ...

2. Запаковать получившуюся строку в одно слово (16 бит).

jcxz, вы молодец! В первом вашем сообщении описали то, к чему я сейчас склоняюсь.
А второе сообщение описывает идею, мною же описанную выше.
В общем, ход мыслей правильный! :drinks:

33 минуты назад, k155la3 сказал:

Если цифры "красивые" - унифицировать кривые.

Да, будут красивые. У меня всё красивое. 
Но только растровые. Закодирую растровыми строками. Повторяющихся будет много. 

26 минут назад, Baser сказал:

Не забывайте, что при подстановочном сжатии вам все равно словарь хранить нужно (те самые кубики).

Помню, помню.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, ViKo сказал:

В общем, ход мыслей правильный! :drinks:

Ну дык - здесь не так уж много вариантов. Если учитывать что ресурсы ограничены (МК).

Можно ещё использовать комбинацию этих методов. Очевидно, что метод 2 проигрывает если по горизонтали в символе часто происходит изменение бита. Например - на буквах Ш/Щ будет до 7-и членов в последовательности. И тогда может и не влезть всё в 16-битное слово. В таких случаях комбинирование методов 1 + 2 решает проблему: те символы, где чередований мало и всё влазит в 16 бит, сжимаем по алгоритму 2. Оставшиеся - по алгоритму 1. И например старший бит результирующего слова будет указывать какой метод использовался для сжатия данной строки пикселов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока речь о цифрах идёт. И, возможно, о символах размерностей и единиц измерений. И запятая с точкой.

А здесь смотрю начертания:
https://ux.pub/luchshie-besplatnye-shrifty-dlya-raboty-s-chislami-i-dannymi/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, ViKo said:

На ЖКИ нужно написать большие цифры, размером, например, 48 х 30 пикселей. Многие байты в символах повторяются, и биты в байтах идут группами.
Какой алгоритм сжатия символов в шрифте здесь можно применить, попроще?

И если символы буду занимать память разного размера, значит, обращаться к ним нужно через массив указателей.  

Вот такой символ 
image.thumb.png.32dfd7eb11999188829a021787d3940b.png

pkzip сожмет в два раза с 288 байт до 135. 
И маленький скромный алгоритм sixpack сожмет до 139 

А RLE наоборот раздует код до 426 байт. Вот тут можно проверить - https://eleif.net/rle.html
Дамп вот такой - 

Spoiler

const uint8_t test_sym[] = {
        0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01,
         0x00, 0x00, 0xF8, 0x03, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFE, 0x1F, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0xFF, 0x3F, 0xE0, 0xFF, 0x3F,
         0x00, 0x80, 0xFF, 0x7F, 0xF0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF,
         0x00, 0xF0, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
         0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0x03, 0xF8, 0x1F, 0xFE, 0x7F, 0x00, 0xFF,
         0x03, 0xFC, 0x07, 0xFC, 0x3F, 0x00, 0xFE, 0x07, 0xFC, 0x07, 0xF8, 0x1F, 0x00, 0xFC, 0x07, 0xFC, 0x03, 0xF8, 0x1F, 0x00, 0xFC,
         0x07, 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xF8, 0x07, 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xF8, 0x07, 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xF8,
         0x07, 0xFC, 0x03, 0xE0, 0x7F, 0x00, 0xF8, 0x07, 0xFC, 0x03, 0xE0, 0x7F, 0x00, 0xF8, 0x07, 0xFC, 0x03, 0xE0, 0xFF, 0x00, 0xF8,
         0x07, 0xFC, 0x07, 0xC0, 0xFF, 0x00, 0xFC, 0x07, 0xFC, 0x0F, 0xF0, 0xFF, 0x01, 0xFC, 0x07, 0xF8, 0x1F, 0xFC, 0xFF, 0x01, 0xFE,
         0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
         0x03, 0xF0, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF,
         0x00, 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x3F, 0xF8, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0x1F, 0xF0, 0xFF, 0x3F,
         0x00, 0x00, 0xFF, 0x07, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0xF8, 0x01, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x01,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char 8
        };

 


Так что не ведитесь на RLE и им подобные. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...