Русский
Русский
English
Статистика
Реклама

Графика в терминале

Эта история началась, когда я узнал о существовании bpytop. Меня поразила детализация графиков и я начал разбираться как это сделано. Оказалось, что для вывода графиков использовались символы алфавита Брайля, представляющие из себя комбинацию из 8 точек: 2 точки в ширину и 4 точки в высоту. Поискав готовые решения, использующие этот подход, я нашел на реддите анонс такого проекта. В первом же комментарии анонса я прочитал:
Это конечно круто, но почему люди просто не переоткроют для себя ReGIS (векторную графику в терминале) и sixel (пиксельную графику в терминале).
До этого момента я ничего не знал про sixel. Копнув глубже я выяснил, что в теории sixel должен поддерживаться xterm-ом. Я запустил xterm на своей ubuntu 20.04 в режиме эмуляции vt340
xterm -xrm "XTerm*decTerminalID: vt340" -xrm "XTerm*numColorRegisters: 256"
выполнил вот такую команду (convert это команда из пакета imagemagick)
clear && convert <(curl -s https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png) sixel:-
и увидел вот это:
image
Вау, работает!

Первым делом я проверил, что по sixel можно найти на хабре. Оказалось, что не много. Есть очень краткая статья 2010-го года без технических подробностей и упоминание в комментариях к статье о портировании Far на линукс. Давайте разберемся, как работает sixel и как с его помощью можно рисовать в совместимом терминале.

Включение режима sixel осуществляется escape последовательностью DCSp1;p2;p3;q, где DCS это Device Control Sequence (может быть либо восьмибитным символом с десятичным значением 144, либо последовательностью двух семибитных символов Escape, P. Параметры p1, p2 и p3 необязательны.
p1 Pixel Aspect Ratio (Vertical:Horizontal)
Не указан 2:1 (default)
0, 1 2:1
2 5:1
3, 4 3:1
5, 6 2:1
7, 8, 9 1:1

Этот параметр является устаревшим. В современном коде его надо выставлять в 0 и использовать атрибут управления растром в sixel строке. Подробности можно посмотреть в документации.

p2 может принимать 3 значения и определяет как терминал рисует фоновый цвет.
p2 Что делает
0 or 2 (default) Пикселы со значением 0 рисуются текущим фоновым цветом.
1 Цвет пикселов со значением 0 не меняется.

Параметр p3 управляет горизонтальным шагом сетки (расстоянием между соседними пикселями). Этот параметр игнорируется если у устройства вывода неизменяемый шаг сетки.

В своих экспериментах в xterm-е я всегда входил в sixel режим при помощи последовательности 0x1bPq (0x1b escape) не используя опциональные параметры.

Выключение sixel режима осуществляется последовательностью ST (String Terminator). ST может быть либо восьмибитным символом с десятичным значением 156 либо последовательностью двух семибитных символов Escape, backslash (ESC \).

После перевода устройства вывода в sixel режим нам нужно подать на него графические данные. Название sixel является производной от six pixels. В режиме sixel мы рисуем за раз столбик из 6-ти пикселов (младший бит является верхним). Отрисовка осуществляется выбранным цветом (об этом чуть позже). Значение одного сиксела может быть от 0 (все биты 0) до 63 (все биты 1). Это значение прибавляется к 63 (ascii ?). Таким образом пустой сиксел представляется символом ?, а сиксел у которого все биты выставлены в 1 символом ~.

Формат sixel предусматривает примитивную компрессию. Конструкция !42~ означает, что мы хотим вывести сиксел ~ 42 раза. В официальной документации не упомянуты ограничения на значения счетчика. При этом известно, что vt240 при дампе графических данных не использует значения больше 255.

При выводе sixel строки есть 2 способа управления курсором. Символ $ переводит курсор в начало той же строки. Это позволяет выводить пикселы разного цвета. Можно выбрать цвет, вывести набор сикселов, вернуться в начало той же строки, выбрать другой цвет, вывести другой набор сикселов. После того, как текущая строка прорисована как надо можно воспользоваться символом - и перевести курсор на следующую строку.

Управлением цветом осуществляется 2 этапа. Сперва нам надо определить цветовые регистры. Это можно сделать командой #NN;p1;p2;p3;p4. Здесь
  • NN номер регистра (от 0 до 255)
  • p1 тип цветового пространства (1 HLS или 2 RGB)
  • p2, p3, p4 значения hue, lightness, saturation для HLS или red, green, blue для RGB. Разрешенные значения параметров от 0 до 100 для всех, кроме hue, который может изменяться от 0 до 360.

Теперь для переключения на определенный цвет нам надо использовать команду вида #NN.

Вооруженные этой информацией мы можем написать код, который выведет нам вот такое изображение:

image

Для сравнения вот как будет выглядеть то же изображение выведенное кодом с использованием символов алфавита Брайля:

image

И то же изображение выведенное кодом с использованием простого ascii:

image
Источник: habr.com
К списку статей
Опубликовано: 22.02.2021 06:06:33
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Ненормальное программирование

Sixel

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru