> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-revert-104359-revert-104251-parquet-single.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Документация по формату вывода изображений в PNG

# PNG

| Ввод | Вывод | Псевдоним |
| ---- | ----- | --------- |
| ✗    | ✔     | ✗         |

<div id="description">
  ## Описание
</div>

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

Размер выходного изображения задаётся настройками
[`output_format_image_width`](/ru/reference/settings/formats/output-format#output_format_image_width) и
[`output_format_image_height`](/ru/reference/settings/formats/output-format#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` задают координаты пикселя. Записи с координатами за пределами
  изображения молча игнорируются. Если несколько записей имеют одинаковые координаты,
  используется последняя из них (алгоритм художника).

<div id="example-usage">
  ## Пример использования
</div>

<div id="implicit-rgb">
  ### Неявные координаты (одна строка на пиксель), RGB
</div>

```sql theme={null}
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;
```

<div id="explicit-grayscale">
  ### Явные координаты, градации серого
</div>

```sql theme={null}
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;
```

<div id="animation">
  ## Анимация
</div>

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

Единица измерения `t` задаётся параметрами
[`output_format_image_time_multiplier_seconds`](/ru/reference/settings/formats/output-format#output_format_image_time_multiplier_seconds)
и
[`output_format_image_time_divisor_seconds`](/ru/reference/settings/formats/output-format#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`. Последний кадр отображается столько же, сколько и предыдущий. Анимация повторяется бесконечно.

```sql theme={null}
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;
```

<div id="streaming-animation">
  ### Потоковая передача кадров
</div>

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

Параметр
[`output_format_image_streaming_animation`](/ru/reference/settings/formats/output-format#output_format_image_streaming_animation)
записывает каждый кадр, как только встречается следующее значение `t`. В памяти хранится только один буфер изображения, а
кадры поступают на вывод, пока запрос ещё выполняется, поэтому программа просмотра может отображать их по мере создания.
При этом:

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

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

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

<div id="terminal-mode">
  ## Отображение изображений в терминале
</div>

По умолчанию формат `PNG` выводит необработанные байты изображения. Параметр
[`output_format_image_terminal_mode`](/ru/reference/settings/formats/output-format#output_format_image_terminal_mode)
заставляет формат вместо этого отображать изображение прямо в терминале с помощью протокола встроенных изображений:

| Значение     | Поведение                                                                                                                                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`\` (пусто) | Выводить необработанные байты изображения (по умолчанию).                                                                                                                          |
| `iterm`      | Использовать протокол встроенных изображений iTerm2.                                                                                                                               |
| `kitty`      | Использовать графический протокол Kitty. Анимация не поддерживается.                                                                                                               |
| `sixel`      | Использовать протокол Sixel. Изображение приводится к фиксированной палитре 6×6×6, а альфа-канал, если он есть, накладывается на чёрный фон.                                       |
| `auto`       | Если вывод идёт в терминал, определить его возможности и использовать `iterm`, `kitty` или `sixel` (в этом порядке); в противном случае выводить необработанные байты изображения. |

```sql theme={null}
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';
```

<div id="format-settings">
  ## Настройки формата
</div>

| Настройка                                     | Описание                                                  | По умолчанию |
| --------------------------------------------- | --------------------------------------------------------- | ------------ |
| `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`          |
