constixel.hpp – минималистичная (262K) С++20 constexpr-библиотека для рендеринга двумерной графики на основе палитр с возможностью вывода изображений в форматах Sixel, Kitty terminal graphics protocol и iTerm2 images protocol в эмуляторах терминала.
На скриншотах – вывод в WezTerm большинства примеров использования.
Основные возможности библиотеки:
- Полностью
constexpr. Весь рендеринг графики, включая генерацию Sixel, может происходить во время компиляции. - Никаких динамических выделений памяти. Буфер и очень немногие внутренние структуры данных могут быть глобальными статическими переменными.
- Минималистичный интерфейс и реализация с единственным заголовочным файлом.
- Буферы на основе 1-, 2-, 4- и 8-разрядных палитр для минимального использования памяти. Предоставляются разумные стандартные палитры. Также предусмотрены 24- и 32-битные буферы, если целью является что-то другое, а не Sixel.
- Простые функции рисования
fill_rect(),fill_round_rect(),draw_line(),fill_circle()и другие. - Рендеринг пропорционального текста, опционально с кернингом, с использованием предварительно отрендеренных текстур шрифтов в формате BMFont, генерируемых пользовательской версией fontbm. Репозиторий включает набор готовых шрифтов (с открытым исходным кодом), которые легко использовать. Поддерживается UTF-8.
- Для уменьшения количества зависимостей предоставляется кодировщик PNG без сжатия.
- Блиттинг необработанных 32-битных RGBA-буферов изображений в буфер на основе палитры (с дизерингом или без него). При необходимости возможна обратная конвертация в RGBA-буфер.
- Различные другие простые операции с изображениями.
Пример использования:
#include "constixel.hpp"
#include <cstring>
consteval auto gen_image_1bit() {
constixel::image<constixel::format_1bit, 256, 256> image;
for (int32_t y = 0; y < 16; y++) {
for (int32_t x = 0; x < 16; x++) {
image.fill_rect(x * 16, y * 16, 16, 16, static_cast<uint8_t>(y + x) & 1);
}
}
return image;
}
int main() {
static const auto image = gen_image_1bit();
printf("image width x height: %d %d x 1bit depth\n", int(image.width()), int(image.height()));
printf("image instance byte size: %d\n", int(image.size()));
size_t count = 0;
image.sixel([&count](char ch) mutable {
putc(ch, stdout);
count++;
});
putc('\n', stdout);
printf("sixel byte size: %d\n", int(count));
}

