Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

PNG

输入 输出 别名

描述

将查询结果渲染为 PNG 图像。这可用作内置的可视化工具。

输出图像的大小由设置 output_format_image_widthoutput_format_image_height 固定 (两者默认值均为 1024) 。结果未覆盖到的像素会填充为黑色 (在 RGB 和灰度图模式下) ,或透明黑色 (在 RGBA 模式下) 。

颜色模式会根据结果的列名和类型自动确定:

模式
r, g, b 8 位 RGB
r, g, b, a 8 位 RGBA
整数类型的 v 8 位灰度图
Float* 类型的 v 8 位灰度图 ([0, 1] 中的值 → [0, 255])
Bool 类型的 v 二值 (渲染为 8 位灰度图:0255)

列名按不区分大小写方式匹配。如果无法明确 判定颜色模式 (例如列名未知、vr/g/b/a 混用,或 r/g/b 中缺少某一列) , 查询会抛出异常。

对于像素通道,整数值会被限制在 [0, 255] 范围内,而浮点值 会被限制在 [0, 1] 范围内,然后再缩放到 [0, 255]

图像中每条记录的位置由以下两种模式之一决定:

  • 隐式 (默认模式——即不存在 xy 时) 。每条记录对应 一个像素;像素按扫描线顺序填充:从左到右、从上到下。
  • 显式 (当存在 xy 列,且两者均为整数类型时) 。 xy 列给出像素坐标。坐标超出 图像范围的记录会被静默忽略。如果多个记录具有相同坐标, 则以最后一条记录为准 (画家算法) 。

使用示例

隐式坐标 (每个像素一行) ,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 列可与 任一坐标模式结合使用。

t 的单位由 output_format_image_time_multiplier_secondsoutput_format_image_time_divisor_seconds确定: 一个 t 单位等于 output_format_image_time_multiplier_seconds / output_format_image_time_divisor_seconds 秒。使用默认值 (160) 时,一个 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 调色板;如果存在 alpha 通道,则会将其合成到黑色背景上。
auto 如果输出是终端,则检测其支持的协议,并使用 itermkittysixel (按此顺序) ;否则输出原始图像字节。
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';

格式 设置

Setting 描述 默认值
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