Краткое руководство о том, как работают изображения и как пиксели могут быть представлены как символы 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 также может быть основой для некоторых интересных фотофильтров и видеоэффектов, которые будут использоваться в социальных сетях. Более того, даже если бы вы не могли использовать эту технику, это все равно было бы хорошим упражнением по кодированию.

Надеюсь, вам понравилась эта статья, и вы узнали что-то новое по пути,

Спасибо за чтение!