Краткое руководство о том, как работают изображения и как пиксели могут быть представлены как символы ASCII - пример кода включен
Я уверен, что многие из вас слышали об ASCII art, технике графического дизайна, в которой для компоновки изображений используется набор печатаемых символов ASCII. Самая простая форма этого искусства - смайлики, такие как :-)
или :-3
. Но можете ли вы представить более сложное изображение с помощью только печатаемых символов ASCII?
Что на самом деле представляет собой изображение
Прежде всего, важно уточнить, как изображение представлено в компьютерных системах. Изображения обычно хранятся на диске в таких форматах, как .png
или .jpg
. Все эти типы файлов имеют похожую структуру: они примерно состоят из заголовка и раздела данных. Первый хранит полезную информацию об изображении, такую как его подпись формата, тогда как второй хранит фактические данные пикселей.
Фактическое изображение, которое вы видите, состоит из пикселей - наименьшего адресуемого элемента растрового изображения, с которым мы все знакомы. Обычно они представлены в виде набора каналов, также называемых цветами. Среди наиболее распространенных значений цвета - классический RGB (красный, зеленый, синий) и RGBA (красный, зеленый, синий, синий). Разница между ними в том, что у последнего есть дополнительный канал, называемый альфа, который определяет непрозрачность изображения. RGBA - это то, с чем мы будем работать, поскольку его также можно использовать для представления пустого фона.
Как перевести пиксели в ASCII
Теперь, когда мы увидели, как представлены изображения, пора поговорить о том, как пиксель можно преобразовать в настоящий символ ASCII. Чтобы понять это, мы должны сначала взглянуть на интенсивность цвета пикселей. Это значение относится к сумме всех каналов пикселя, деленной на сумму максимальных значений, которые могут иметь каналы (в данном случае 255).
С этого момента я буду использовать Python для примеров кода из-за его простоты и удобочитаемости, но не стесняйтесь использовать любую технологию, которую вы предпочитаете. Я также буду использовать
PIL
библиотеку изображений, чтобы код был как можно более простым и абстрактным.
Первая строка импортирует статические типы, необходимые для ясности. Если вы не знаете, что это такое, посмотрите мою статью о подсказках по типу.
В этом фрагменте кода я определил новый Pixel
тип, Tuple
из четырех целых чисел, каждое из которых представляет один из каналов в пикселе RGBA. Затем я определил функцию, которая извлекает интенсивность заданного пикселя. Сначала он суммирует все значения каналов, а затем делит результат на максимальное значение, которого могут достичь каналы пикселя, чтобы эффективно получить процент интенсивности.
После того, как мы вычислили интенсивность пикселя, пришло время сопоставить его с символом ASCII. Для этого мы должны определить набор символов, который мы будем использовать для представления пикселей.
Набор символов упорядочен от самого легкого, пробел, до самого тяжелого, @
. Это означает, что чем ярче пиксель, тем больше места занимает его соответствующий символ ASCII.
Функция сопоставляет заданную интенсивность пикселей с символом в наборе. Результат intensity * len(CHARACTERS)
округляется, поскольку индексы должны быть целыми числами.
Теперь давайте склеим эти фрагменты кода с помощью простого скрипта:
Просмотр ASCII-арта
После того, как мы получили строковое представление изображения в формате ASCII, мы должны найти способ просмотреть его графически. Самый простой способ сделать это - распечатать его на консоли. Поскольку изображения обычно организованы в ряды пикселей, при их печати мы также должны соответственно использовать символы новой строки.
Здесь я написал простую функцию, которая выводит изображение ASCII на консоль и как ее можно вызвать из основной функции:
Давайте посмотрим на этот сценарий в действии! Мы преобразуем простое изображение, подобное этому:
Предположим, мы вызвали файл изображения image.png
и сценарий converter.py
, команда будет выглядеть так:
python converter.py image.png # Or if you are on a Unix-like system and the script is executable ./converter.py image.png
Это приведет к следующему выводу на консоль:
Как видите, картинка немного искажается из-за расстояния между линиями. Это ограничение многих эмуляторов терминала, но есть простое решение.
Визуальные улучшения с использованием HTML
Мы уже видели, как преобразовать изображение в его представление ASCII, но было бы лучше, если бы вы сохранили результат в реальном файле. Но почему именно HTML?
- Поддерживается всеми веб-браузерами.
- Вы можете легко увеличивать и уменьшать масштаб в зависимости от масштаба изображения.
- Он по-прежнему может состоять только из символов ASCII.
Напишем функцию для сохранения полученного изображения в файл HTML:
Теперь, когда мы завершили наш конвертер изображений, давайте посмотрим на несколько интересных изображений и их версию в формате ASCII:
Вот ссылка на репозиторий GitHub проекта, на котором я основал эту статью. Я также напрямую включу исходный код в суть ниже, если у вас не хватило времени:
Если кому-то интересно, я также создал простой бесплатный веб-сайт, который конвертирует ваши изображения в ASCII. Однако я отказываюсь от того, что это несерьезный проект и может содержать ошибки и уязвимости, поэтому даже отдаленно не думайте о том, чтобы полагаться на него ни в чем.
Заключение
В этой статье вы вкратце узнали, как структурированы файлы изображений и, что наиболее важно, как преобразовать отдельные пиксели в соответствующие им символы ASCII.
Этот вид ASCII-арта можно использовать, например, в качестве элементов дизайна на веб-странице. Преобразование изображений ASCII также может быть основой для некоторых интересных фотофильтров и видеоэффектов, которые будут использоваться в социальных сетях. Более того, даже если бы вы не могли использовать эту технику, это все равно было бы хорошим упражнением по кодированию.
Надеюсь, вам понравилась эта статья, и вы узнали что-то новое по пути,
Спасибо за чтение!