PNG 형식
PNG 형식
PNG 형식은 쿼리 결과를 PNG 이미지로 렌더링하는 내장된 시각화 도구예요. 이미지의 크기는 output_format_image_width와 output_format_image_height 설정(기본 1024)으로 고정되며, 색상 모드는 결과의 컬럼 이름과 타입에서 자동으로 결정됩니다. t 컬럼이 있으면 애니메이션 PNG(APNG)를 생성하기도 해요.
출처: 문서
본문
| Input | Output | Alias |
|---|---|---|
| ✗ | ✔ | ✗ |
설명 (Description)
쿼리 결과를 PNG 이미지로 렌더링합니다. 이것은 내장된 시각화 도구로 유용해요. 출력 이미지의 크기는 output_format_image_width와 output_format_image_height 설정(둘 다 기본 1024)으로 고정됩니다. 결과가 덮지 않는 픽셀은 검은색(RGB 및 그레이스케일 모드) 또는 투명한 검은색(RGBA 모드)으로 채워집니다.
색상 모드는 결과의 컬럼 이름과 타입에서 자동으로 결정됩니다:
| Columns | Mode |
|---|---|
| r , g , b | 8-bit RGB |
| r , g , b , a | 8-bit RGBA |
| v of integer type | 8-bit grayscale |
| v of Float* type | 8-bit grayscale (values in [0, 1] → [0, 255] ) |
| v of Bool type | Binary (rendered as 8-bit grayscale: 0 or 255 ) |
컬럼 이름은 대소문자를 구분하지 않고 일치됩니다. 색상 모드를 명확하게 결정할 수 없으면(예: 알 수 없는 컬럼 이름, v와 r/g/b/a 혼합, 또는 r/g/b 중 하나 누락) 쿼리는 예외를 발생시킵니다.
픽셀 채널의 경우 정수 값은 [0, 255]로 클램프되고, 부동 소수점 값은 [0, 1]로 클램프된 다음 [0, 255]로 스케일링됩니다.
이미지에서 각 레코드의 위치는 두 가지 모드 중 하나로 결정됩니다:
- 암시적(Implicit)(기본값 —
x도y도 없을 때). 각 레코드는 단일 픽셀에 해당하며, 픽셀은 스캔라인 순서(왼쪽에서 오른쪽, 위에서 아래)로 채워집니다. - 명시적(Explicit)(
x와y컬럼이 모두 있고 둘 다 정수 타입일 때).x와y컬럼이 픽셀 좌표를 제공합니다. 이미지 밖의 좌표를 가진 레코드는 조용히 무시됩니다. 같은 좌표의 레코드가 여러 개면 마지막 것이 우선합니다(화가의 알고리즘, painter’s algorithm).
사용 예시 (Example usage)
암시적 좌표(행당 픽셀), 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;
애니메이션 (Animation)
결과에 정수 타입의 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;
프레임 스트리밍 (Streaming the frames)
기본적으로 모든 프레임은 메모리에 수집되어 쿼리가 끝날 때 기록되며, 이는 t의 각 고유 값마다 이미지 버퍼 하나를 유지하고 t가 어떤 순서로든 도착할 수 있게 합니다.
output_format_image_streaming_animation 설정은 t의 다음 값이 보이는 즉시 각 프레임을 기록합니다. 메모리에는 이미지 버퍼 하나만 유지되고, 쿼리가 아직 실행되는 동안 프레임이 출력에 도달하므로 뷰어가 생성되는 대로 표시할 수 있습니다.
대가로:
t는 비감소(non-decreasing)여야 하며, 그렇지 않으면 쿼리가 예외를 발생시킵니다. 필요하면ORDER BY t를 추가하세요.- 헤더를 써야 할 때 프레임 수를 알 수 없으므로
acTL청크는 정확한 수 대신 상한을 선언합니다. 브라우저는 그런 파일을 재생하지만, 선언된 수를 신뢰하는 디코더(예:Pillow와 일부 커맨드라인APNG도구)는 마지막 실제 프레임 뒤에 오류를 보고합니다. 단일 프레임의 애니메이션은 예외입니다. 그 프레임이 기록될 때쯤 전체 결과를 이미 읽었으므로 수를 정확히 선언하고 출력이 사양을 준수합니다.
인라인 터미널 이미지 프로토콜은 전체 데이터스트림을 단일 페이로드로 운반하므로 프레임이 터미널에 일찍 도달할 수 없고, 이 설정은 거기서 사용되는 메모리 양에만 영향을 줍니다. 버퍼링된 페이로드가 전송되기 전에 정확한 프레임 수가 패치되므로 상한에 관한 주의사항은 적용되지 않습니다.
애니메이션은 iterm 터미널 모드에서만 표시됩니다. sixel 프로토콜은 애니메이션을 전혀 표현할 수 없고, Kitty 그래픽스 프로토콜은 애니메이션 데이터스트림이 아닌 별도의 프레임별 명령 흐름으로만 애니메이션을 하므로 첫 프레임만 표시할 것입니다. 두 모드 모두 t 컬럼이 있는 결과를 거부합니다.
터미널에 이미지 표시 (Displaying images in the terminal)
기본적으로 PNG 형식은 원시 이미지 바이트를 기록합니다. output_format_image_terminal_mode 설정은 형식이 대신 인라인 이미지 프로토콜을 사용해 이미지를 터미널에 직접 렌더링하게 합니다:
| Value | Behaviour |
|---|---|
| “ (empty) | 원시 이미지 바이트를 기록합니다(기본값). |
| 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';
형식 설정 (Format settings)
| Setting | Description | Default |
|---|---|---|
| output_format_image_width | 출력 이미지의 너비(픽셀). | 1024 |
| output_format_image_height | 출력 이미지의 높이(픽셀). | 1024 |
| output_format_image_terminal_mode | 인라인 터미널 이미지 프로토콜(위 참조). | “ (empty) |
| output_format_image_time_multiplier_seconds | t 컬럼의 시간 단위 분자(초). | 1 |
| output_format_image_time_divisor_seconds | t 컬럼의 시간 단위 분모(초). | 60 |
| output_format_image_streaming_animation | t가 진행되는 즉시 각 프레임 기록(위 참조). | 0 |