Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

PNG

Entrée Sortie Alias

Description

Affiche le résultat d’une requête sous forme d’image PNG. C’est utile comme outil de visualisation intégré.

La taille de l’image de sortie est définie par les paramètres output_format_image_width et output_format_image_height (tous deux définis par défaut sur 1024). Les pixels non couverts par le résultat sont remplis de noir (en modes RGB et en niveaux de gris) ou de noir transparent (en mode RGBA).

Le mode colorimétrique est déterminé automatiquement à partir des noms et des types des colonnes du résultat :

Colonnes Mode
r, g, b RGB 8 bits
r, g, b, a RGBA 8 bits
v de type entier niveaux de gris 8 bits
v de type Float* niveaux de gris 8 bits (valeurs dans [0, 1][0, 255])
v de type Bool Binaire (rendu en niveaux de gris 8 bits : 0 ou 255)

Les noms des colonnes sont comparés sans tenir compte de la casse. Si le mode colorimétrique ne peut pas être déterminé de manière non ambiguë (par exemple, noms de colonnes inconnus, mélange de v avec r/g/b/a, ou absence de l’un de r/g/b), la requête lève une exception.

Pour les canaux de pixel, les valeurs entières sont limitées à [0, 255] et les valeurs à virgule flottante à [0, 1], puis mises à l’échelle vers [0, 255].

La position de chaque enregistrement dans l’image est déterminée selon l’un des deux modes suivants :

  • implicite (par défaut — lorsque ni x ni y n’est présent). Chaque enregistrement correspond à un seul pixel ; les pixels sont remplis dans l’ordre de balayage : de gauche à droite, de haut en bas.
  • explicite (lorsque les colonnes x et y sont présentes, toutes deux de type entier). Les colonnes x et y donnent les coordonnées du pixel. Les enregistrements dont les coordonnées sont en dehors de l’image sont ignorés silencieusement. Si plusieurs enregistrements ont les mêmes coordonnées, le dernier prévaut (algorithme du peintre).

Exemple d’utilisation

Coordonnées implicites (une ligne par pixel), RVB

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;

Coordonnées explicites, niveaux de gris

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;

Animation

Si le résultat comporte une colonne t de type integer, le format produit un PNG animé (APNG) au lieu d'une image fixe. Les enregistrements sont regroupés en images par la valeur de t, qui correspond au décalage temporel relatif de l'image. Chaque image est indépendante : le canevas est vide au début de chaque image et, dans le mode de coordonnées implicites, le curseur repart du coin supérieur gauche. La colonne t peut être associée à l'un ou l'autre mode de coordonnées.

L'unité de t est définie par output_format_image_time_multiplier_seconds et output_format_image_time_divisor_seconds : une unité de t correspond à output_format_image_time_multiplier_seconds / output_format_image_time_divisor_seconds secondes. Avec les valeurs par défaut (1 et 60), une unité de t correspond à 1/60e de seconde.

Une image est affichée jusqu'au début de l'image suivante ; sa durée correspond donc à la différence entre deux valeurs consécutives de t. La dernière image est affichée aussi longtemps que l'image qui la précède. L'animation se répète indéfiniment.

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;

Diffusion des images

Par défaut, toutes les images sont collectées en mémoire et écrites à la fin de la requête, ce qui conserve un tampon d’image par valeur distincte de t et permet à t d’arriver dans n’importe quel ordre.

Le paramètre output_format_image_streaming_animation écrit chaque image dès que la valeur suivante de t est reçue. Un seul tampon d’image est conservé en mémoire et les images sont envoyées vers la sortie alors que la requête est encore en cours d’exécution, ce qui permet à un visualiseur de les afficher au fur et à mesure de leur production. En contrepartie :

  • t doit être non décroissant ; sinon, la requête lève une exception. Ajoutez ORDER BY t si nécessaire.
  • Le nombre d’images n’est pas connu au moment où l’en-tête doit être écrit ; le fragment acTL déclare donc une limite supérieure plutôt que le nombre exact. Les navigateurs lisent un tel fichier, mais les décodeurs qui se fient au nombre déclaré (par exemple, Pillow et certains outils APNG en ligne de commande) signalent une erreur après la dernière image réelle. Une animation à une seule image fait exception : le résultat complet a été lu lorsque cette image est écrite, de sorte que le nombre est déclaré avec exactitude et que la sortie est conforme à la spécification.

Comme un protocole d’image intégré au terminal transporte l’intégralité du flux de données dans une seule charge utile, les images ne peuvent pas parvenir au terminal de manière anticipée, et ce paramètre n’y affecte que la quantité de mémoire utilisée. Le nombre exact d’images est corrigé dans la charge utile mise en mémoire tampon avant son envoi ; la réserve concernant la limite supérieure ne s’applique donc pas.

Une animation n’est affichée qu’en mode terminal iterm. Le protocole sixel ne peut pas représenter une animation, et le protocole graphique Kitty n’anime qu’au moyen d’un flux distinct de commandes par image, et non d’un flux de données animé ; il n’afficherait donc que la première image. Les deux modes rejettent un résultat contenant une colonne t.

Affichage des images dans le terminal

Par défaut, le format PNG écrit les octets bruts de l’image. Le paramètre output_format_image_terminal_mode fait plutôt afficher l’image directement dans le terminal au moyen d’un protocole d’image intégré :

Valeur Comportement
`` (vide) Écrit les octets bruts de l’image (comportement par défaut).
iterm Utilise le protocole d’image intégré d’iTerm2.
kitty Utilise le protocole graphique de Kitty. Ne peut pas afficher d’animation.
sixel Utilise le protocole Sixel. L’image est réduite à une palette fixe 6×6×6 et le canal alpha, le cas échéant, est composé sur un fond noir.
auto Si la sortie est un terminal, détecte ses capacités et utilise iterm, kitty ou sixel (dans cet ordre) ; sinon, écrit les octets bruts de l’image.
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';

Paramètres du format

Paramètre Description Par défaut
output_format_image_width Largeur de l’image de sortie en pixels. 1024
output_format_image_height Hauteur de l’image de sortie en pixels. 1024
output_format_image_terminal_mode Protocole intégré d’image de terminal (voir ci-dessus). `` (vide)
output_format_image_time_multiplier_seconds Numérateur de l’unité de temps de la colonne t, en secondes. 1
output_format_image_time_divisor_seconds Dénominateur de l’unité de temps de la colonne t, en secondes. 60
output_format_image_streaming_animation Écrit chaque image dès que t progresse (voir ci-dessus). 0
Navigation