Я работаю над программой (на C / C ++), в которой пользователь должен взять выбранное пользователем изображение и преобразовать его в искусство ASCII (используя SQL). До сих пор я был в состоянии для пользователя выбрать изображение и отобразить это изображение в оттенках серого в окне.
Однако в настоящее время у меня возникают трудности с сортировкой символов ASCII в виде массива уровней яркости и последующим сопоставлением одного символа с областью пикселей.
Я знаю, что мне нужно будет использовать циклы for, но я пока не могу найти ничего полезного в Интернете. Спасибо: D
Нет никакого разумного способа сделать это, и существующие программы ASCII-art просто используют предопределенный порядок символов. То есть char myASCII[] = " .,:ilwW";
ASCII персонажи не имеют собственной серости, потому что это зависит только от того, как они нарисованы на вашем экране — каким шрифтом, размером, горизонтальным и вертикальным интервалом и какими цветами.
Тем не менее: можно сделать обоснованное предположение. Для большинства шрифтов пробел «полностью белый», точка остановки в большинстве шрифтов будет маленькой точкой, запятая немного больше, и так далее. Все, что вам нужно, это соотношение из черно-белых пикселей, для каждого отображаемого символа.
Найдите (или создайте) растровую версию шрифта, который вы собираетесь использовать, или близкий к нему. Поскольку большинство шрифтов ASCII на самом деле очень близки по своему дизайну, вы можете даже использовать простой растровый шрифт 8×8 (не многие шрифты будут иметь !
это «тяжелее», чем W
— если вы найдете то, что делает, найдите другое). Поскольку вы собираетесь использовать его для ASCII-искусства, вам, вероятно, нужны только моноширинные шрифты. Рисовать ASCII искусство с помощью пропорциональных шрифтов возможно, но гораздо сложнее.
Зацикливайтесь на каждом символе и считайте черные пиксели. Как правило, пространство будет иметь 0
, полная остановка 1
и что-то вроде #
будет 16 или около того. (Эй, смотрите! Здесь вы можете использовать for
цикл!)
точный серость каждого символа может быть представлена value/area
где area
это полный размер растрового изображения. Но вы не заинтересованы в абсолютной стоимости! Обычный диапазон ASCII не содержит символа, который должен быть «полностью черным». Чтобы узнать родственник серый, разделите значение для каждого символа на максимальная значение, которое вы нашли для всего шрифта. Таким образом, пространство будет 0
, символ «максимальное значение» будет 1
и все остальные символы будут иметь значение между ними. (На самом деле, если ваш символ «Пробел» содержит черные пиксели, вычтите их также из начальных значений. Просто, чтобы обрисовать общую идею; лучше не использовать такой странный шрифт.)
В итоге вы получите 95 значений — по одному для каждого от пробела (# 32) до тильды (# 126). Если вы хотите использовать все символы в выводе, вы готовы к работе. Сортировка символов по уровню серого. Для каждого серого входного пикселя (уровень от 0 до 255) разделите его на 255, чтобы получить его в том же диапазоне, что и значение карты вашего персонажа. Затем напечатайте символ с уровнем ближе всего к нему. (Это самый простой метод, но его можно оптимизировать различными способами.)
Если вы хотите ограничить оттенки серого меньшим диапазоном значений / символов, создайте меньший массив со значениями, ближайшими к нужным уровням. Например, если вы хотите 16 уровней серого, найдите символы, наиболее близкие к 0, 1/15, 2/15 … 15/15.
Смотрите также шаги 5 и 6 мой ответ на связанный вопрос.