如果你在终端复用器里跑过chafa、viu这类看图工具,一定见过下面这种画面:图片没出现,屏幕上反而多出一堆ESC开头的乱码。问题通常不在工具本身,而在于中间的终端复用层没有把图片协议完整透传下去。Zellij 是目前最活跃的 Rust 终端复用器之一,它在这块也有明显短板。好在仓库里最近出现了一条很直接的主线:Zellij: Support the Kitty Image Protocol。
这篇文章就围绕这条主线展开。先解释终端里显示图片为什么这么麻烦,再讲 Kitty Image Protocol 的核心工作方式,然后给出一套可以在 Zellij 里验证图片渲染的完整流程。全文不堆概念,重点放在可执行操作、终端兼容性判断和常见坑位排查上。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | 终端复用器 + 图像协议支持 |
| 目标能力 | 在 Zellij 的 pane 中正确显示或透传 Kitty 协议图像 |
| 开发语言 | Rust |
| 适用环境 | Linux、macOS、WSL 等主流 Unix 环境 |
| 协议取向 | Kitty Image Protocol,与 Sixel、iTerm2 inline image 协议并列 |
| 前端终端要求 | 需要 kitty、WezTerm、Ghostty、Konsole 等支持该协议的终端 |
| 后端工具 | chafa、viu、timg 等支持 Kitty 协议输出的图片预览工具 |
| 主要场景 | 终端图片预览、TUI 图像应用、远程开发、会话协作 |
| API 接口 | 不涉及 HTTP API,通过终端转义序列和标准输入输出交互 |
| 批量任务 | 可通过 Zellij 布局同时管理多个 pane,实现批量图片预览 |
| 当前状态 | 以仓库开发主线或 PR 形式推进,正式版本以官方发布为准 |
这条主线补上的不是一个新软件,而是 Zellij 对终端图像生态的兼容能力。要判断它值不值得关注,先得理解终端图片协议在整个链路里的位置。
2. 背景:终端里显示图片为什么这么麻烦
终端本质上是一张字符网格。传统终端只能显示字符、颜色和属性,没有“图片”这个原生概念。要在终端里显示图片,必须依赖额外的图像协议。不同终端模拟器支持的协议不一样,这就导致同一个chafa命令在你的终端里正常,在另一个终端里却变成乱码。
目前主流图像协议有三种。
| 协议 | 代表支持方 | 特点 |
|---|---|---|
| Sixel | VT340、xterm、较新版本的 VTE 终端 | 历史最久,基于六像素色块,支持色彩相对受限 |
| iTerm2 inline image protocol | iTerm2 及部分兼容终端 | 通过 OSC 1337 序列内联传输图片,实现简单 |
| Kitty Image Protocol | kitty、WezTerm、Ghostty、Konsole 等 | 高色深、支持动画、支持任意分辨率缩放,性能好 |
Kitty Image Protocol 是这几类里设计比较现代的一个。它由 kitty 终端提出,后来被 WezTerm、Konsole、Ghostty 等终端逐步采纳。由于传输效率高,且能处理大尺寸图片和帧动画,很多终端图像工具默认优先走这个协议。
Zellij 的特殊之处在于它自己实现了一个内置终端模拟器。也就是说,Zellij 不是一个简单的输入输出转发层,它需要理解 pane 里正在发生的终端转义序列。对于普通文本和 ANSI 颜色没问题,但遇到图片协议这种“重数据”转义序列,如果内置模拟器不认识,图片数据就会被当作普通字符流处理,最终在屏幕上变成一片乱码。这也是“Zellij 不支持 Kitty 图片协议”的最直接影响。
3. Kitty Image Protocol 工作原理
Kitty Image Protocol 本质上是通过一套特殊转义序列把图片数据传进终端。整个数据流大致长这样:
发送方 (chafa/viu) ↓ 转义序列 ESC_G + 图片数据 + ESC\ ↓ 终端复用层 (Zellij) ↓ 前端终端模拟器 (kitty/WezTerm/Ghostty) ↓ 屏幕渲染协议的核心是\x1b_G开头的控制序列,后面带上参数和图片数据,以\x1b\\结束。发送方会把图片按 base64 编码后放进转义序列,终端收到后再解码、渲染。
从协议名称就能看出,这个过程要求“链路两端都支持”。前端终端必须认识\x1b_G序列,否则图片区会显示成垃圾字符。而中间如果隔着 Zellij 这类终端复用器,它也必须把这些序列识别出来。要么原样转发给前端终端,要么自己解析并重新计算图片在 pane 里的位置和尺寸。
这里有一个技术上的关键点:Zellij 支持多个 pane 和浮动 pane,图片并不总是占满整个终端窗口。Zellij 需要知道当前 pane 的坐标和尺寸,才能决定图片在屏幕上落在哪个区域。如果是多个 pane 同时显示图片,协议还要处理不同 pane 之间的区域重叠问题。所以“支持 Kitty Image Protocol”不是简单加一个白名单,更涉及 pane 布局和图像裁剪的配合。
对于普通用户来说,不需要记住复杂的转义序列格式,但需要理解一条原则:图片显示是否成功,取决于整条链路上最弱的一环。前端终端不支持,Zellij 再努力也没用;Zellij 不支持,前端终端能力再强也收不到有效数据。
4. Zellij 支持 Kitty Image Protocol 意味着什么
把支持前后的使用体验放到一起,就能看出这条主线解决的是哪些具体问题。
| 使用场景 | 支持之前 | 支持之后 |
|---|---|---|
| 在 pane 里用 chafa 显示图片 | 乱码或空白 | 图片正常显示或完整透传 |
| 在远程服务器上预览图片 | 链路中间容易丢数据 | 只要本地终端支持,可完整呈现 |
| 用 Zellij 共享会话给别人看 | 对方终端看到的可能是乱码 | 在全链路支持的情况下可正常展示 |
| 在 TUI 应用里嵌入图像 | 图像区域无法渲染 | 可以按 pane 尺寸渲染图像 |
| 在布局里同时打开多个图片预览 | 多个 pane 的图像相互干扰 | 各 pane 独立渲染,互不干扰 |
典型场景包括:
- 在终端文件管理器里快速预览图片,不需要切出终端。
- 在编辑器的集成终端里查看 Markdown 中的图片、截图或监控图表。
- 通过 SSH 到远程服务器,直接预览服务器上的图片素材。
- 用 Zellij 的 pane 布局同时观察多张图片,比如批量检查训练集、测试图、渲染结果。
这里需要注意边界:即使 Zellij 支持了协议,最终渲染仍然依赖前端终端。如果你在 GNOME Terminal 或旧版 xterm 里跑 Zellij,前端终端不认识 Kitty 协议,图片还是显示不出来。所以“Zellij 支持 Kitty Image Protocol”解决的是中间层的问题,而不是终端能力的问题。
5. 前置条件与终端兼容性检查
在开始之前,先确认自己手里的环境是否满足最低条件。按下面顺序检查。
5.1 前端终端确认
确认你正在用的终端模拟器是否支持 Kitty Image Protocol。目前比较稳的支持方包括:
- kitty
- WezTerm
- Ghostty
- Konsole(较新版本)
- 其他明确在更新日志中标注支持该协议的终端
如果你的终端不支持,后面所有测试都很难正常通过。还有一种情况需要特别提醒:一些终端虽然支持协议,但默认关闭,需要在终端配置里手动打开。遇到图片显示异常时,先排除这一项。
5.2 Zellij 版本
Zellij 对 Kitty Image Protocol 的支持还在推进中。如果你需要使用开发版本,建议从官方仓库获取最新的稳定版或开发版。不要依赖系统自带的过老版本。
zellij --version如果输出版本比较旧,建议先升级。
5.3 图片预览工具
准备一个支持 Kitty 协议输出的终端图片工具,推荐下面三个:
chafa --version viu --version timg --versionchafa支持多协议自动探测,viu使用简单,timg偏向于终端幻灯片预览。三个至少装一个,测试时建议用chafa,因为它的输出信息更直观。
5.4 准备测试图片
准备一张 PNG 或 JPEG 图片。使用自己生成的测试图、系统自带壁纸或可自由分发的素材都行,注意版权合规即可。
mkdir -p ~/test_images cp /path/to/test.png ~/test_images/test.png到这里,工具链已经齐了。
6. 安装 Zellij 与准备环境
Zellij 的安装方式很常规。推荐优先使用官方安装脚本,也可以走系统包管理器。
# macOS brew install zellij # Arch Linux sudo pacman -S zellij # 使用官方安装脚本 curl -sSf https://install.zellij.dev | sh官方安装脚本地址可能随仓库更新调整,如果访问不了,直接去 Zellij 仓库 README 里找 Latest release 的下载方式。
安装完成后先做一次最基础的环境检查,确认 Zellij 能正常启动。
zellij --version zellij setup --checkzellij setup --check会输出当前环境的基本状态。如果这条命令在你本机不存在,说明版本较老,直接以官方文档为准。
启动 Zellij:
zellij默认会进入一个干净的会话,带一个 pane。看到底部状态栏出现 Zellij 的快捷键提示,说明环境没问题。此时先按Ctrl+p或Ctrl+o查看 pane 操作菜单,确认基本操作可用,再进入下一步功能验证。
7. 功能验证:在 Zellij 中显示图片
这里给出一套以现有工具链为基础的验证流程。
7.1 单独 pane 中显示图片
在 Zellij 会话里,Ctrl+p打开 pane 菜单,创建新 pane,然后运行:
chafa ~/test_images/test.png如果 Zellij 和前端终端都支持 Kitty 协议,终端里会直接渲染出图片。如果输出的是乱码,说明当前环境没有走通协议。此时可以先在 Zellij 外部的普通终端里运行同一个命令,确认工具和终端本身没有问题。
chafa也支持强制指定协议:
chafa --format=kitty ~/test_images/test.png--format=kitty明确告诉 chafa 使用 Kitty 协议输出。这样能更快定位问题出在 Zellij 还是前端终端。
7.2 分屏显示多张图片
Zellij 的核心优势是 pane 管理。验证分屏场景比单 pane 更有意义,因为协议在多个 pane 共存时的处理更复杂。
# 在已有会话中创建第二个 pane zellij action new-pane然后在两个 pane 里分别运行:
chafa ~/test_images/test.png chafa ~/test_images/test2.png观察结果:
- 两张图片是否都能显示。
- 图片是否被正确限制在各自 pane 的区域内。
- 调整 pane 大小后,图片是否重新渲染而不是错位。
如果调整 pane 大小后图片变形或位置错乱,说明 Zellij 对协议图像的重新布局还有待完善。这是测试时需要重点记录的问题。
7.3 浮动 pane 场景
Zellij 支持浮动 pane。图片预览放在浮动 pane 里,可以临时覆盖在当前工作区上,适合快速查看图片而不干扰主体布局。
zellij action toggle-pane-focus浮动 pane 中的图片渲染和普通 pane 有些差异,因为浮动 pane 的位置是由 Zellij 直接管理的。如果普通 pane 正常但浮动 pane 异常,问题基本指向 Zellij 对浮动 pane 区域裁剪的处理。
7.4 SSH 远程场景
Zellij 常用于远程服务器。测试方式如下:
- 本地终端选择支持 Kitty 协议的终端。
- SSH 登录远程服务器。
- 在远程服务器中启动 Zellij。
- 在 pane 里运行
chafa显示远程图片。
关键点在于:图片数据经过 SSH 通道传递,最终由本地终端渲染。如果本地终端不支持协议,整个链路失败;如果 SSH 配置里有奇怪的LC_*环境变量或强制伪终端参数,也可能干扰协议序列。
测试时不要开复杂的终端嵌套,先保持一层 Zellij,减少变量。
8. 用 Zellij 布局做批量图片预览
Zellij 的优势在于 session 和 layout。如果你有一批图片要快速过目,可以写一个简单的脚本,在 Zellij 里批量打开多个 pane 进行预览。
下面是一个逻辑示例,具体命令需要按你的 Zellij 版本调整,因为zellij action的语法在不同版本有差异。
#!/usr/bin/env bash IMAGE_DIR="$HOME/test_images" for img in "$IMAGE_DIR"/*.png; do zellij action new-pane -- chafa "$img" sleep 0.5 done这段脚本的作用是:遍历test_images目录下的所有 PNG 图片,每张图片在单独的 pane 中启动chafa预览。
实际运行前先确认两个问题:
zellij action new-pane是否支持--传递命令。chafa是否在你当前的 PATH 中。
如果action语法不支持,可以改为打开多个 pane 后手动运行。批量的核心价值在于验证:系统在多个 pane 同时接收 Kitty 协议数据时,是否稳定、是否丢帧、是否占满 CPU。
批量测试后重点看三个指标:
- 是否所有 pane 都正常渲染图片。
- 整机 CPU 占用是否明显升高。
- 切换 pane 焦点时是否会触发重绘异常。
如果批量场景能稳定通过,那么这个能力就已经具备进入日常使用的条件。
9. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 图片区域全是乱码 | 前端终端不支持 Kitty 协议 | 在 Zellij 外部终端直接运行chafa | 更换支持协议的终端,或让 chafa 使用symbols输出模式 |
| 图片显示为空白块 | Zellij 透传失败,或 pane 区域未正确裁剪 | 检查 Zellij 版本,查看当前 pane 位置 | 升级 Zellij,重启会话后重试 |
| 单 pane 正常,分屏后错位 | Zellij 对 pane 交接区域处理不完整 | 调整 pane 大小,观察图片是否跟随 | 记录 Zellij 版本,等待新版本修复,或临时用浮动 pane |
| 远程 SSH 场景图片断裂 | 本地终端不支持协议,或 SSH 转发异常 | 本地先测一遍chafa,再进 Zellij 测 | 本地终端换成支持协议的产品,去掉多余 SSH 包装层 |
| 图片颜色偏色或发灰 | 前端终端或 Zellij 对彩色协议支持不一致 | 换一张小尺寸图片测试 | 更新终端和 Zellij,关闭终端的低色彩模式 |
| 批量打开图片时卡顿 | 图片过大或 pane 过多 | 观察 CPU 占用和内存占用 | 先压缩图片,再减少同时打开的 pane 数量 |
| 协议序列被当作普通输出 | Zellij 版本过旧,内置终端模拟器不识别 | 检查版本号 | 升级到包含该主线的版本 |
排查思路的核心是缩小问题范围。先在 Zellij 外部的终端里跑chafa,能排除工具和前端终端的问题。再进入 Zellij 跑同样的命令,能确认问题是否出在 Zellij 这一层。如果 Zellij 外部正常、内部异常,问题基本锁定在 Zellij 对协议的处理上。
10. 性能与资源观察
终端图片显示链路里的性能压力,主要不在 Zellij,而在图片数据本身的传输和渲染。
10.1 SSH 带宽与转义序列体积
Kitty 协议传输图片时会把图片编码进转义序列。一张几 MB 的图片经过 base64 编码后体积会变大,如果走 SSH 链路,高分辨率图片会明显增加带宽占用。远程预览大图时如果觉得“卡”,可以先检查图片体积。
ls -lh ~/test_images/test.png10.2 CPU 占用
图片解码和渲染主要发生在前端终端一侧。Zellij 作为中间层,如果只是透传协议,CPU 占用不会太高。但如果 Zellij 需要根据 pane 尺寸重新计算图片区域,在频繁缩放 pane 或多 pane 并行渲染时,CPU 占用会上升。
10.3 如何降低资源消耗
- 图片预览前先缩放图片,不要直接预览几十 MB 的原始工程文件。
- 控制同时打开的图片 pane 数量。
- 在 SSH 远程场景中,优先使用 JPEG 或压缩过的 PNG。
- 如果只是快速看图,可以用
chafa --format=symbols走字符块模式,完全不依赖图片协议。
注意,这里不涉及显存占用。终端图片渲染通常走 CPU 和系统内存,与 GPU 无关。
11. 最佳实践与使用建议
Zellij 支持 Kitty Image Protocol 之后,终端图片显示这件事会变得更可靠,但在实际使用中还是有一些工程层面的注意点。
11.1 保持“前端终端”和“Zellij 能力”分离
排查问题时,永远先确认前端终端支持什么协议,再讨论 Zellij 的问题。前端终端不支持时,Zellij 无论怎么升级都无法独立完成图片渲染。
11.2 布局里预留图片预览区域
如果你经常在终端里看图片,可以在 Zellij 布局文件里预留一个固定 pane 作为图片预览区。布局文件使用 Zellij 的配置格式,常见写法如下:
layout { pane size="60%" { plugin location="zellij:tab-bar" } pane size="40%" { command="bash" } }实际字段以官方文档为准,这里只是示意。布局的核心思路是:一个 pane 用于主任务,另一个 pane 用于图片预览,两者互不干扰。
11.3 批量预览前先做小规模测试
批量打开 10 个以上的图片 pane 前,先用 3 个 pane 测试稳定性。确认协议透传稳定后再扩展数量,避免一次把会话搞崩。
11.4 素材版权和授权
如果你在终端里预览的图片涉及人脸、版权素材、内部数据,注意只使用自己有权使用的素材。不要把未经授权的图片放到共享会话或公开演示中。
11.5 关注官方发布日志
Kitty Image Protocol 支持目前还在推进中。最终落地形式、默认开启还是需要配置、版本号要求,都以 Zellij 官方发布日志为准。不要只看第三方教程里的截图,要自己在目标版本上跑一遍。
12. 总结与下一步
Zellij 支持 Kitty Image Protocol 这件事,解决的痛点是终端复用层对图像协议的不兼容。它不会取代前端终端,也不会取代 chafa 这类预览工具,而是让整条链路在 Zellij 内部变得更顺畅。
最值得先验证的是你的前端终端是否支持协议。只要终端支持,Zellij 层面的问题通常可以用升级版本解决。最容易踩的坑是前端终端不支持协议,却把问题归结到 Zellij 上。建议收藏这篇文章提到的排查步骤,下次在 Zellij 里跑chafa出现乱码时,直接按链路逐层缩小范围。
下一步可以做的事:
- 确认你手里的 Zellij 版本是否包含这条主线。
- 用
chafa在单个 pane、分屏 pane、浮动 pane 三个场景各测一遍。 - 如果图片能在多个 pane 中稳定渲染,把 Zellij 布局调成适合你工作流的方案。
- 继续关注 Zellij 官方仓库的更新日志,看后续是否对协议透传做更多优化。
终端图片显示是个小能力,但直接影响日常使用体验。这一功能落地后,终端管文件、终端看截图、终端做远程预览的工作流都会顺手很多。