← Electerm 博客

让图片直接显示在 Electerm 终端里

2026-09-23
终端图片sixelitermkittyssh技巧

让图片直接显示在 Electerm 终端里

你在远程机器上 ls 一个装满截图的目录,得到的只是一串文件名。hero-final-v2-REALLY.png 到底是不是想要的那张?常规做法是一段绕路:用 SFTP 下载下来、本地打开、再删掉——或者开个浏览器预览,或者干脆猜。

Electerm 可以把这段绕路省掉。给这个书签打开 支援终端图像 开关,图片就会内联渲染在终端滚动区里,命令在哪里执行、图就出现在哪里——就像上面的横幅演示的那样。不用下载,不用切应用。

底层用的是 xterm.js 官方的 @xterm/addon-image 插件,一次支持三种线上传输协议,而不是一种:

  • SIXEL——DEC 年代的位图协议(ESC P ... ESC \),至今仍是终端图形的通用语
  • iTerm 内联图片(IIP)——imgcat 用的 OSC 1337 协议
  • Kitty 图形协议(TGP)——部分支持,上游仍标注为 WIP

只要对端的程序会说这三种中的任意一种,electerm 就能把它画出来。

打开它(按书签单独控制)

这个开关是按书签控制的,不是全局的——图形解码要吃内存,所以只有需要的会话才付这个代价。

  1. 打开书签编辑(书签面板 → 右键 → 编辑,或新建书签)。
  2. SSH 书签:在 SSH 设置区找到 支援终端图像 并打开。本地终端书签:它在 auth 选项卡里。
  3. 保存并重连。图片插件只在终端创建时加载一次(src/client/components/terminal/mixins/term-init.js),已经打开的标签页必须重连才能生效。

底层代码就是这几行:

if (tab.enableTerminalImage) {
  const ImageAddon = await loadImageAddon()
  this.imageAddon = new ImageAddon({
    pixelLimit: 33554432
  })
  term.loadAddon(this.imageAddon)
}

pixelLimit: 33554432 把单张图片限制在约 3200 万像素以内,其余(SIXEL 滚动、调色板、存储 FIFO、被淘汰图片的占位符)都保持插件默认值。插件是懒加载的——开关没开,这段代码连下载都不会下载。

试一试:三条单行命令

不用装什么冷门东西就能看到效果,选你手头工具本来就支持的协议即可。

用 chafa 输出 SIXEL——大多数 Linux 机器上最快的冒烟测试:

chafa -f sixel logo.png

其它能输出 SIXEL 的:lsix、ImageMagick(convert logo.png sixel:-)、set term sixel 的 gnuplot,以及一切基于 libsixel 的东西。

用 imgcat 输出 iTerm 内联图片——imgcat 脚本只是把文件 base64 编码塞进 OSC 1337 序列,所以在纯 SSH 上就能用,服务端不需要任何支持:

imgcat ./screenshots/hero-final-v2-REALLY.png

这里支持 PNG、JPEG、GIF 和 QOI(不支持动画,只画第一帧)。图片可以缩放到超出视口(比如 width=200%),光标会停在图片最后一行的下一个单元格, 后续输出读起来很自然。

用 icat 输出 Kitty 图形:

kitty +kitten icat photo.jpg

插件里的 Kitty 支持上游还在 WIP,基础渲染没问题,冷僻子命令可能会静默忽略。

如果你看到的是转义乱码(^[[?1;2Sq#0;2;...)而不是图,说明开关没开,或者开了之后标签页还没重连。

实际用起来是什么感觉

不用走 SFTP 就能验远程素材。 imgcat 连看五张候选图,选中,收工。图片留在滚动区里,Shift+PageUp 翻回去还能找到。

图在哪里算,就在哪里看。 训练脚本吐一张 SIXEL 曲线、gnuplot 画图、给数据集打 chafa 缩略图——图出现在产生它的数字旁边,出现在产生它的机器上。

**在 SSH 上看带图的文档。**man 手册做不到,但现代 CLI 工具可以直接在 --help 或状态输出里嵌架构图和截图。

光标行为值得知道:SIXEL 默认滚动开启,图片顶到视口底部时会把屏幕顶上去,光标停在图片最后一行的第一列(VT340 模式)。IIP 图片则把光标放在图片最后一行的下一个单元格。不管哪种,下一个提示符都会从一个合理的位置开始。

一些值得知道的细节

  • 默认关闭是有原因的:内存。 图片解码在 JavaScript 里做,解码过程中会持有完整的 RGBA 缓冲。3200 万像素上限加上插件的 FIFO 图片存储(滚动区里被淘汰的图片会显示占位图案),能保证单个标签页是安全的——但十个标签页同时看 4K 截图还是会累加。不需要的地方就别开。
  • **大块输出会绕过合并批量。**electerm 的会话服务对超过 16 KB 的数据块直接透传、不做合并,这样几 MB 的 imgcat 序列也不会让解析器错位。不用你配置;这就是为什么 5 MB 的图片后面跟着的提示符不会乱。
  • **关键字高亮会主动让路。**高亮插件遇到包含 DCS 序列(ESC P)的写入会直接跳过,所以高亮逻辑永远不会污染正在传输的 SIXEL 流。
  • **别跟终端背景图搞混。**背景图设置是在文字后面铺一张水印。这个功能画的是真正的终端内容输出——进滚动区、跟随字号缩放、清屏会清掉。
  • 缩放行为。 已经在屏幕上的图片在字号变化时会重塑,保持所占单元格不变。终端窗口缩放时,被右截断的图片可能向右扩展;被底部截断的不会向下生长。
  • 安全提示。 图片序列会查询终端度量(插件默认启用 CSI 14/16/18 t 尺寸上报)。在普通开发机上这无害,而且正是工具给图片适配窗口大小的依据——但如果你面对的是不可信输出的威胁模型,那就保持关闭。

一个看得见图的终端

大多数终端功能都是关于文字的——字体、颜色、搜索、高亮。这个功能承认:有时候答案本来就不是文字。一张缩略图、一张曲线、一张截图:把它画在命令执行的地方,整整一类"下载下来再看"的中断就消失了。

如果还没试过:编辑一个书签,打开 支援终端图像,重连,然后对任意图片跑一句 chafa -f sixel