Kitty 图形协议[1] 用于使终端支持高清图形功能。

基本使用

协议的构成如下:

<ESC>_G<control data>;<payload><ESC>\

其中 control data 是由逗号分割的 key=value 对。payload 是由 base64 编码的数据。

协议对 PNG 提供原生支持,如果需要渲染 PNG 数据,只需要使用:

<ESC>_Gf=100;<payload><ESC>\

其中 payload 是 base64 编码的 PNG 二进制数据。

如果同时还使用了压缩协议,则必须提供 payload 的大小

传输介质

通过 key t 能够指明 payload 的含意,具体有:

value含意

d

payload 包含了需要渲染的二进制数据。

f

payload 代表了一个文件路径。此文件是一个 regular 文件。

t

payload 指向临时文件路径,终端将会在读取后将此文家删除。

s

共享内存对象。

渲染数据

下面给出了渲染数据的例子:

use std::collections::HashMap;

use base64::Engine;

use base64::engine::general_purpose;

#[derive(Debug, Default)]
struct KittyBuilder<T: AsRef<[u8]>> {
    opts: HashMap<String, String>,
    payload: T,
}

impl<T: AsRef<[u8]>> KittyBuilder<T> {
    fn build(self) -> String {
        let opts: Vec<String> = self
            .opts
            .into_iter()
            .map(|(key, value)| format!("{key}={value}"))
            .collect();
        format!(
            "\x1b_G{};{}\x1b\\",
            opts.join(",").to_string(),
            general_purpose::STANDARD.encode(self.payload)
        )
    }

    fn opt(mut self, key: String, value: String) -> Self {
        self.opts.insert(key, value);
        self
    }

    fn payload(mut self, payload: T) -> Self {
        self.payload = payload;
        self
    }
}
fn main() {
    let pic1 = KittyBuilder::default()
        .opt("f".into(), "100".into())
        .opt("a".into(), "T".into())
        .opt("t".into(), "f".into())
        .payload("1.png") (1)
        .build();
    print!("{}", pic1);

    let pic1 = KittyBuilder::default()
        .opt("f".into(), "100".into())
        .opt("a".into(), "T".into())
        .payload(std::fs::read("1.png").unwrap()) (2)
        .build();
    print!("{}", pic1);
}
  1. 直接渲染数据

  2. 要求渲染指定路径的数据

Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx