ASCII Art - Сортировка массива символов ASCII по уровням яркости (C/C++)

Я работаю над программой (на C/C++), в которой пользователь должен взять выбранное пользователем изображение и преобразовать его в искусство ASCII (используя SQL). До сих пор мне удавалось, чтобы пользователь мог выбрать изображение и отобразить его в оттенках серого в окне.

Однако в настоящее время у меня возникают трудности с сортировкой символов ASCII в виде массива уровней яркости, а затем сопоставлением одного символа с областью пикселей.

Я знаю, что мне нужно будет использовать циклы for, но пока я не могу найти ничего полезного в Интернете. Спасибо :D


person INeedHelp    schedule 07.05.2015    source источник
comment
Вы должны добавить часть своего кода, чтобы мы могли видеть, что у вас уже есть и где именно проблема.   -  person Wouter    schedule 07.05.2015
comment
Проблема в том, что я понятия не имею, как анализировать группы пикселей и сопоставлять их с символом ASCII той же «яркости».   -  person INeedHelp    schedule 07.05.2015
comment
См. jp2a.   -  person Sinan Ünür    schedule 07.05.2015
comment
Возможно, вы захотите выбрать один язык, C или C++.   -  person MSalters    schedule 07.05.2015
comment
Среди прочего, это будет зависеть от шрифта и цветов, используемых для отображения. Нет такой вещи, как яркость символа 65, это просто число, представляющее некоторый печатный глиф, то, как он отображается, зависит от используемого шрифта.   -  person David Rodríguez - dribeas    schedule 07.05.2015
comment
Пока спасибо за помощь..... хорошо, в таком случае, как бы вы определили (в коде), сколько «белого» и «черного» имеет каждый символ, чтобы определить, насколько ярким выглядит каждый символ, а затем отсортировать их в порядке того, как ярко они появляются на экране?   -  person INeedHelp    schedule 07.05.2015


Ответы (3)


символы ASCII не имеют внутреннего серого цвета, потому что это зависит только от того, как они отображаются на вашем экране — каким шрифтом, размером, горизонтальным и вертикальным интервалом и какими цветами.

Тем не менее: можно сделать обоснованное предположение. Для большинства шрифтов пробел «полностью белый», точка в большинстве шрифтов будет маленькой точкой, запятая немного больше и так далее. Все, что вам нужно, — это соотношение пикселей черного и белого для каждого отображаемого символа.

  1. Найдите (или создайте) растровую версию шрифта, который вы собираетесь использовать, или близкую к ней. Поскольку большинство шрифтов ASCII на самом деле очень близки по своему дизайну, вы даже можете использовать простой растровый шрифт 8x8 (немногие шрифты будут иметь !, который «тяжелее», чем W — если вы найдете такой, найдите другой). Поскольку вы собираетесь использовать его для графики ASCII, вам, вероятно, понадобятся только моноширинные шрифты. Рисовать ASCII-арт пропорциональными шрифтами возможно, но гораздо сложнее.

  2. Переберите каждый символ и подсчитайте черные пиксели. Как правило, пробел будет иметь 0, точка 1, а что-то вроде # будет иметь 16 или около того. (Эй, смотрите! Здесь вы можете использовать цикл for!)

  3. Точная степень серости каждого символа может быть представлена ​​как value/area, где area – это полный размер растрового изображения. Но вас не интересует абсолютное значение! Обычный диапазон ASCII не содержит символов, которые должны быть «полностью черными». Чтобы узнать относительную серость, разделите значение для каждого символа на максимальное значение, которое вы нашли для всего шрифта. Таким образом, пробел будет 0, символ "максимального значения" будет 1, а все остальные символы будут иметь промежуточное значение. (На самом деле, если ваш пробел содержит черные пиксели, вычтите и их из начальных значений. Просто для того, чтобы наметить общую идею: вам лучше не использовать такой странный шрифт.)

  4. Вы получите 95 значений — по одному от пробела (#32) до тильды (#126). Если вы хотите использовать все символы в своем выводе, вы готовы к работе. Отсортируйте символы по уровню серого. Для каждого входного пикселя серого (уровень от 0 до 255) разделите его на 255, чтобы получить его в том же диапазоне, что и значение вашей карты символов. Затем выведите символ с ближайшим к нему уровнем. (Это самый простой метод, но его можно оптимизировать различными способами.)

  5. Если вы хотите ограничить оттенки серого меньшим диапазоном значений/символов, создайте меньший массив со значениями, наиболее близкими к нужным вам уровням. Например, если вы хотите 16 уровней серого, найдите символы, наиболее близкие к 0, 1/15, 2/15... 15/15.

См. также шаги 5 и 6 мой ответ на соответствующий вопрос.

person Jongware    schedule 27.06.2015
comment
Я применил аналогичный подход здесь: jod.li/optimal- character-choices-for-ascii-art-in-php Результаты меня вполне устраивают. - person luvzfootball; 30.11.2020

$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.

Вот стандартная шкала серого от темного к светлому (или наоборот, в зависимости от предпочитаемого вами цвета дисплея).

person Ahsen Khan    schedule 31.05.2021

Нет разумного способа сделать это, и существующие программы с ASCII-графикой просто используют предопределенный порядок символов. т.е. char myASCII[] = " .,:ilwW";

person MSalters    schedule 07.05.2015