LINUX.ORG.RU

Посоветуйте алгоритмы сжатия битмапных шрифтов

 


1

2

Есть желание пожать битмапные фонты для тощих эмбедов. Т.к. с памятью не очень, а фонтов хочется хранить побольше, чтобы показывать Material Design во всей красе. https://github.com/littlevgl/lv_examples/issues/26#issuecomment-473279547 - тут примеры «картинок», которые в итоге хочется отрисовывать.

- Фонты размером от 8px до 32px
- Пиксели черно-белые, обычно от 1 до 4 бит (зависит от предпочтений юзера).

Вырезание не используемых глифов и обрезку краёв пропускаем, это уже сделано, вопрос именно про дальнейшую компрессию. Пожеланию по алгоритму:

- декомпрессия должна быть простой, и не требовать много памяти
- сжатие желательно от 2 раз на шрифтах от 16px. Иначе мало смысла заморачиваться.

Можете посоветовать что-то более-менее готовое под такую задачу? Не абстрактно «юзай RLE, энтропию и посмотри сжатие факсов», а что-то более проработанное?

PS. То что внутри u8g2 я смотрел, но оно только под 1-битные пиксели, без оттенков.

★★★★★

Я конечно абстрактно. Но упростить шрифт как у тебя картинках до линий и дуг. Svg примитивы весят очень мало.

bga_ ★★★★
()
Последнее исправление: bga_ (всего исправлений: 1)
Ответ на: комментарий от bga_

Тогда ты в итоге получишь рендерер векторных шрифтов, который слишком тяжелый. Даже на десктопах сначала в битмапы отрисовывают, но там памяти много.

В общем, надо что-то более приземленное и проверенное для того типа данных что я описал.

Vit ★★★★★
() автор топика
Ответ на: комментарий от frob

RLE как принцип меня устраивает. Но без конкретных нюансов имплементации это разговор ни о чем. В отличие от какого-нибудь deflate/inflate, RLE не является стандартом, это только описание общего принципа.

Vit ★★★★★
() автор топика
Ответ на: комментарий от ip

По ссылке человек изобрел 2D delta encoding :). Про однобитность оптимальным ответом было бы «почитай JBIG2». Но к сожалению, чаще нужны 4-битные или хотя бы 2-битные битмапы.

На ардуине народ бьется за то, как утоптать символы 8х8 в AVR. А мне надо Material Design на ARM. Ресурсов побольше, но и требования выше.

Внешнего флеша нет. QSPI мало кто поддерживает в тощих чипах. А с толстыми заморачиваться нет смысла - там уже маячит raspberry с линуксом и QT.

Vit ★★★★★
() автор топика

Если нет градиентных переходов (а вроде нет то можно что то вроде DXT1 налабать(усреднение до ближнего) ) фонты чёрно белые, а картинки RGBA? Если да, то ещё отрезать все каналы до одного grayscale uint8

Deleted
()
Ответ на: комментарий от no-such-file

Хаффман = энтропийное кодорование. В начале упоминал про него.

Я принципы-то какбэ примерно знаю. Интересуют конкретные имплементации, по которым собрана готовая статистика. Лениво самому пилить, но запилю если до этого дойдет.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Там и так уже все отрезано. Я ж написал - картинки черно-белые, по 1-4 бита на пиксель. Не на цвет, а на пиксель.

Там на самом деле не оттенки серого, а прозрачность. Чтобы монохромные шрифты на любой фон нормально накладывались, с антиалиасингом.

Vit ★★★★★
() автор топика
Ответ на: комментарий от no-such-file

Бессмысленное усложнение. Он анализирует байты. А у меня пиксели по 2-4 бита. Поэтому zlib будет пытаться найти в группах пикселей смысл, которого там нет.

Ну и он не юзает специфику картинок, типа 2D-предобработки (вроде дельта-кодирования строк).

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Vit

Бессмысленное усложнение. Он анализирует байты

gzip жмёт pcf шрифты в 4 раза, можно взять твои шрифты и тупо проверить. Не очень понимаю, отчего ты вздумал выёживаться?

no-such-file ★★★★★
()
Ответ на: комментарий от Vit

рендерер векторных шрифтов, который слишком тяжелый

Говорят, когда-то был такой Tektronix 4014 с векторными шрифтами, и был он именно потому, что память для растра была слишком дорогая.

DonkeyHot ★★★★★
()
Ответ на: комментарий от no-such-file

PCF шрифты «толстые». В отличие от моих. Если глубина твоего понимания предмета находится на уровне что я выеживаюсь - значит ты зря сюда пришел, потому что от тебя нет ни какого толка.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

PCF шрифты «толстые». В отличие от моих

Ну залей куда-нибудь сэмпл, что-ли.

значит ты зря сюда пришел

Да нет, это ты зря сюда пришёл с требованиями подать тебе на блюдечке алгоритм для твоих волшебных шрифтов. Ты даже не удосужился потыкать варианты которые у тебя под руками, чтобы определиться, достаточно их тебе или нет, и если нет, то чем не устраивают. А потом уже задавать вопросы. Так ведётся конструктивный диалог. Если тебе нужно чтобы за тебя сделали работу - пиши в job.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Ну залей куда-нибудь сэмпл, что-ли.

Не вижу смысла напрягаться ради тебя лично.

Да нет, это ты зря сюда пришёл с требованиями подать тебе на блюдечке алгоритм для твоих волшебных шрифтов.

Твое мнение в данном вопросе меня не интересует. Есть другие люди, разберемся без... тебя.

Ты даже не удосужился потыкать варианты которые у тебя под руками, чтобы определиться, достаточно их тебе или нет, и если нет, то чем не устраивают. А потом уже задавать вопросы. Так ведётся конструктивный диалог. Если тебе нужно чтобы за тебя сделали работу - пиши в job.

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

Vit ★★★★★
() автор топика

А чем самое обыкновенное .png не устраивает?

Немного не понятно, при чем тут JBig2, так как этот алгоритм относится к категории алгоритмов сжатия монохромных изображений, на которых присутствуют повторяющиеся эквивалентные по форме силуэты (буквы).

В «шрифте» все буквы встречаются ровно 1 раз, поэтому профита от JBig2 не будет.

Вам нужно растр с буковками сжимать или файлик с вырезанными растрами отдельных букв? В последнем случае рекомендую посмотреть на обыкновенное 8-битное .png с палитрой, и различными фильтрами (вспоминаю только 1 Paeth) которые уменьшают размер байтового потока в конечном сжатом файле.

nikitos ★★★
()
Ответ на: комментарий от nikitos

У меня растр с буковками, где либо 4 либо 16 оттенков прозрачности (2 и 4 бита на пиксель). При этом больше всего повторений белого цвета, чуть меньше черного, остальное не повторяется.

В PNG насколько помню все начинается от 1 байта на пиксель. А тут более мелкие квантили.

- Если прикидывать на глаз, то куча ухищрений на мелких квантилях просто потеряет смысл.
- Ну и плюс требование по простоте декодера.

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

На глаз, думал брать I3BN и дополнительно ограничить, чтобы правило применялось только для черного и белого. Как альтернативный вариант - перекодировать строки дельтой, и энкодить по RLE только белый цвет.

Насчет переменной длинны не уверен. Есть сомнения, из-за того что сами «картинки» небольшие (до 32*32) и в пикселях битов мало.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

У меня очень большое подозрение, что правильно подобранный RLE будет намного проще

Так png вроде на RLE и работает, он преобразует исходняк под него. Не?

Deleted
()
Ответ на: комментарий от Vit

BMP умеет RLE. Поскольку он afair не умеет «разные RLE», то видимо это какой-то «RLE стандартный для BMP». Описание наверняка валяется у MS-а где-то рядом с описанием BMP.

frob ★★★★★
()
Ответ на: комментарий от Deleted

https://en.wikipedia.org/wiki/Portable_Network_Graphics#Compression

Не. Там предподготовка + deflate. Причем из-за коротких строк не получится менять фильтр построчно, а из-за мелких картинок словарь можно делать только общим на весь фонт.

Скорее всего оно того не стоит.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Не. Там предподготовка + deflate

Сорян. Попутал. Но межстрочную delta я бы всё-равно не оставлял без внимания.

Deleted
()
Ответ на: комментарий от Deleted

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

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Это не проблема.

Информация в компьютере представляет из себя битональные, то есть «1» и «0», состояния, вообще-то.

iZEN ★★★★★
()
Ответ на: комментарий от Vit

В PNG насколько помню все начинается от 1 байта на пиксель.

Нет, можно и 1 бит на пиксель (насчет 2 или 4 не помню, но стоит проверить). Даже с палитрой. Имел опыт, прикольно смотрится розовое по прозрачному. Мне такое извращение нужно было чтоб сделать кастомный TMS поверх космоснимка (монохромная топокарта с розовыми линиями высот :)).

В качестве примера советую посмотреть на проект optipng, именно с его вывода я и получал однобитные .png-хи.

nikitos ★★★
()
Последнее исправление: nikitos (всего исправлений: 1)
Ответ на: комментарий от Vit

4 либо 16 оттенков прозрачности (2 и 4 бита на пиксель)

Тут если сильно хочеться извратиться можно разделить на битовые слайсы и получить (применить) 2 или 4 раза монохромный алгоритм.

nikitos ★★★
()
Ответ на: комментарий от nikitos

Угу, недоглядел. Есть мелкобитные пиксели для чернобелого режима.

Только вот в фильтре и компрессоре их потом гвоздят все равно байтами. То есть жаться будут только длинные серии (от 4 или от 8 пикселей соответственно).

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от nikitos

О, живой свидетель применения битовых плоскостей :)

А можешь на пальцах объяснить, какой там получается выигрыш в компрессии по сравнению с другими алгоритмами?

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Зависит от объектов на изображении, которое приходится сжимать. Для ваших букв может выстрелить, так как каждая битовая плоскость будет содержать немного покусанные, но подобные друг другу буквы, а не белый шум (как в случае обычных фотографий в младших битах интенсивности).

Возможно, разделять на битовые плоскости нужно не по-тупому, а используя код Грея. Но надо пробовать.

nikitos ★★★
()
Ответ на: комментарий от nikitos

Я про спутниковые фотки спрашивал. Там имело смысл битовые плоскости втуливать? Если имело, то какой выигрыш.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Ты не забывай что RLE очень просто рисовать и памяти совсем не надо

bga_ ★★★★
()
Ответ на: комментарий от Vit

Нет, там не имело смысла, так как всего 1 бит. Поверх спутниковых фоток накладывались монохромные 1-битные изображения с кастомной палитрой.

nikitos ★★★
()
Ответ на: комментарий от drsm

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

Спасибо за ссылку.

Vit ★★★★★
() автор топика
Ответ на: комментарий от nikitos

https://github.com/littlevgl/lv_font_conv/issues/8

Напостил тут результатов. Непосредственно сама компрессия особо много не дает, но и не мешает. Основной профит идет от:

- обрезки битмапов до bounding box
- переход с 4bits/pixel => 3bits/pixel

Сама компрессия на { font-size: 36px } уменьшает итоговый файл в полтора раза. На { font-size: 16px } - процентов на 10. Там уже начинает сказываться толщина таблицы кернинга.

Предфильтрацию строк вместо дельты сделал XOR-ом - его легко считать блочно для любой разрядности пикселей, а шаманство с энтропией нам пофик.

ХЗ можно ли тут еще что-то выжать, сохранив простоту распаковки.

Vit ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.