Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

PNG

Ввод Вывод Псевдоним

Описание

Отображает результат запроса в виде PNG-изображения. Это удобно как встроенный инструмент визуализации.

Размер выходного изображения задаётся настройками output_format_image_width и output_format_image_height (обе по умолчанию равны 1024). Пиксели, не покрытые результатом, заполняются чёрным цветом (в режимах RGB и градаций серого) или прозрачным чёрным (в режиме RGBA).

Цветовой режим автоматически определяется по именам столбцов и типам результата:

Столбцы Режим
r, g, b 8-битный RGB
r, g, b, a 8-битный RGBA
v целочисленного типа 8-битные градации серого
v типа Float* 8-битные градации серого (значения в [0, 1][0, 255])
v типа Bool Двоичный (отображается как 8-битные градации серого: 0 или 255)

Имена столбцов сопоставляются регистронезависимо. Если цветовой режим нельзя определить однозначно (например, из-за неизвестных имён столбцов, смешения v с r/g/b/a или отсутствия одного из r/g/b), запрос генерирует исключение.

Для пиксельных каналов целочисленные значения ограничиваются диапазоном [0, 255], а значения с плавающей точкой — диапазоном [0, 1], после чего масштабируются до [0, 255].

Положение каждой записи в изображении определяется одним из двух режимов:

  • Неявный (по умолчанию — когда нет ни x, ни y). Каждая запись соответствует одному пикселю; пиксели заполняются в порядке сканирования: слева направо, сверху вниз.
  • Явный (когда присутствуют столбцы x и y, оба целочисленного типа). Столбцы x и y задают координаты пикселя. Записи с координатами за пределами изображения молча игнорируются. Если несколько записей имеют одинаковые координаты, используется последняя из них (алгоритм художника).

Пример использования

Неявные координаты (одна строка на пиксель), RGB

SELECT
    toUInt8(x * 25) AS r,
    toUInt8(y * 25) AS g,
    toUInt8((x + y) * 12) AS b
FROM
(
    SELECT number % 10 AS x, intDiv(number, 10) AS y FROM numbers(100)
)
INTO OUTFILE 'gradient.png'
FORMAT PNG
SETTINGS output_format_image_width = 10, output_format_image_height = 10;

Явные координаты, градации серого

SELECT
    toInt32(x) AS x,
    toInt32(y) AS y,
    toUInt8(intensity) AS v
FROM points
INTO OUTFILE 'points.png'
FORMAT PNG
SETTINGS output_format_image_width = 512, output_format_image_height = 512;

Анимация

Если результат содержит столбец t целочисленного типа, формат создаёт анимированный PNG (APNG) вместо статичного изображения. Записи группируются в кадры по значению t, которое задаёт относительное смещение времени кадра. Каждый кадр представляет собой независимое изображение: в начале каждого кадра холст пуст, а в режиме неявных координат курсор снова начинается с верхнего левого угла. Столбец t можно использовать с любым режимом координат.

Единица измерения t задаётся параметрами output_format_image_time_multiplier_seconds и output_format_image_time_divisor_seconds: одна единица t равна output_format_image_time_multiplier_seconds / output_format_image_time_divisor_seconds секунды. При значениях по умолчанию (1 и 60) одна единица t равна 1/60 секунды.

Кадр отображается до начала следующего кадра, поэтому его длительность равна разности между двумя последовательными значениями t. Последний кадр отображается столько же, сколько и предыдущий. Анимация повторяется бесконечно.

SELECT
    number % 60 AS t,
    toInt32(intDiv(number, 60) % 64) AS x,
    toInt32((number * 7) % 64) AS y,
    toUInt8(255) AS v
FROM numbers(60 * 64)
INTO OUTFILE 'animation.png'
FORMAT PNG
SETTINGS output_format_image_width = 64, output_format_image_height = 64;

Потоковая передача кадров

По умолчанию все кадры собираются в памяти и записываются по завершении запроса. Для каждого уникального значения t при этом хранится отдельный буфер изображения, а значения t могут поступать в любом порядке.

Параметр output_format_image_streaming_animation записывает каждый кадр, как только встречается следующее значение t. В памяти хранится только один буфер изображения, а кадры поступают на вывод, пока запрос ещё выполняется, поэтому программа просмотра может отображать их по мере создания. При этом:

  • t должен быть неубывающим; в противном случае запрос генерирует исключение. При необходимости добавьте ORDER BY t.
  • Количество кадров неизвестно на момент записи заголовка, поэтому фрагмент acTL указывает верхнюю границу вместо точного количества. Браузеры воспроизводят такой файл, но декодеры, доверяющие указанному количеству (например, Pillow и некоторые инструменты командной строки для APNG), сообщают об ошибке после последнего фактического кадра. Исключение составляет анимация из одного кадра: к моменту записи этого кадра весь результат уже прочитан, поэтому количество указывается точно, а вывод соответствует спецификации.

Поскольку встроенный протокол отображения изображений в терминале передаёт весь поток данных как единую полезную нагрузку, кадры не могут поступить в терминал раньше, и этот параметр влияет здесь только на объём используемой памяти. Точное количество кадров вносится в буферизованную полезную нагрузку перед отправкой, поэтому ограничение, связанное с верхней границей, не применяется.

Анимация отображается только в режиме терминала iterm. Протокол sixel вообще не поддерживает анимацию, а графический протокол Kitty поддерживает анимацию только через отдельный поток покадровых команд, а не через анимированный поток данных, поэтому отобразит лишь первый кадр; оба режима отклоняют результат со столбцом t.

Отображение изображений в терминале

По умолчанию формат PNG выводит необработанные байты изображения. Параметр output_format_image_terminal_mode заставляет формат вместо этого отображать изображение прямо в терминале с помощью протокола встроенных изображений:

Значение Поведение
`` (пусто) Выводить необработанные байты изображения (по умолчанию).
iterm Использовать протокол встроенных изображений iTerm2.
kitty Использовать графический протокол Kitty. Анимация не поддерживается.
sixel Использовать протокол Sixel. Изображение приводится к фиксированной палитре 6×6×6, а альфа-канал, если он есть, накладывается на чёрный фон.
auto Если вывод идёт в терминал, определить его возможности и использовать iterm, kitty или sixel (в этом порядке); в противном случае выводить необработанные байты изображения.
SELECT toUInt8(x * 25) AS r, toUInt8(y * 25) AS g, toUInt8((x + y) * 12) AS b
FROM (SELECT number % 10 AS x, intDiv(number, 10) AS y FROM numbers(100))
FORMAT PNG
SETTINGS output_format_image_width = 10, output_format_image_height = 10, output_format_image_terminal_mode = 'auto';

Настройки формата

Настройка Описание По умолчанию
output_format_image_width Ширина выходного изображения в пикселях. 1024
output_format_image_height Высота выходного изображения в пикселях. 1024
output_format_image_terminal_mode Протокол вывода изображений прямо в терминале (см. выше). `` (пусто)
output_format_image_time_multiplier_seconds Числитель единицы времени столбца t в секундах. 1
output_format_image_time_divisor_seconds Знаменатель единицы времени столбца t в секундах. 60
output_format_image_streaming_animation Записывать каждый кадр при увеличении t (см. выше). 0
Navigation