邮件里直接显示图片_在 iTerm2 里显示图片

7596b525306736550648ef0d2b5290a0.png

今天一早看到沈雕墨老师给 SQLFlow 贡献的一个 pull request。感觉非常有意思。跟大家分享一下。

SQLFlow 和命令行客户端

SQLFlow 扩展 SQL 语法。其中一个扩展是

SELECT ... TO EXPLAIN aTrainedModel USING TreeExplainer;

当用户执行这样一条语句的时候,SQLFlow 会调用 SHAP 图示化地解释一个训练好的模型 aTrainedModel。SHAP 的输出是一个 PNG 图像。SQLFlow 通常的用户界面是 Jupyter Notebook,它可以显示图片,如 SQLFlow 主页上的动图展示的。截图如下:

29d19b31b92173040cf61ccfab931496.png

SQLFlow 还有一个命令行界面,类似 MySQL 的 mysql 命令。沈雕墨老师的这个 pull request 使得这个命令行工具在执行上述扩展语法的语句时,也可以展示 SHAP 输出的图片。不过要求 terminal 程序能支持显示图片。沈雕墨老师尝试了 macOS 自带的 Terminal.app,发现支持的图像颜色不多。最好用 iTerm2。

832fd7a619217010b8cf32206e47210b.png

(等下回抓一个好看一点儿的图)

OSC 编码

为了能 review 沈雕墨老师的 code,我也学习了一下 iTerm 的展示图片的能力:

Images - Documentation - iTerm2 - macOS Terminal Replacement​www.iterm2.com
4f64f4e604a112c3bd71c9587db20b98.png

基本原理是

iTerm2 extends the xterm protocol with a set of proprietary escape sequences. In general, the pattern is:
ESC]1337;key=value^G

上述1337被称为一个OSC code,全称是 operating system command terminal control sequences,是用来控制 terminal 的行为的。比如,在几乎任何 terminal 窗口里输入如下命令,可以利用 OSC code 0 来修改窗口标题为“唉呀妈呀”。

printf "033]0;唉呀妈呀a"

判断 iTerm2

上述 OSC code 1337 不是每个 terminal 程序都支持的。SQLFlow 需要知道自己是不是运行在 iTerm2 里,才能决定是否输出图片,还是应该只是打印一个指向图片的 URL。

为此,可以下载和运行这个 shell 脚本 https://github.com/gnachman/iterm2-website/blob/master/source/utilities/it2check

在 iTerm2 里运行它,结果是0(表示是 iTerm2)。

$ source ./it2check ; echo $?
0

在 Terminal.app 里运行它,结果是1(表示不是 iTerm2)。

$ source ./it2check ; echo $? 
1

展示图片

在 iTerm2 里要展示一个图像文件,可以用脚本 imgcat。下载之后,在 iTerm2 里运行下述命令即可。

./imgcat a.png

这个命令干了什么呢?仔细读一读源码,发现它向标准输出打印了如下内容

033]1337;File=name=图像文件名;size=图像大小;inline=0:图像内容(Sixel编码);a

我以前没有用过 Sixel 图像格式,所以查了一下 Wikipedia,原来是一种把图像编码成 ASCII 序列的编码方式。

写一个 Go 程序来展示图片

知道关键是输出 Sixel 格式的图像给 iTerm,那么用任何语言写一个程序,向标准输出写一个 Sixel 格式的图像文件,即可在 iTerm2 里显示图片了。这样我也就理解沈雕墨老师的 pull request 了。为了方便大家了解,我简化这个 pull request 成如下命令行程序 imgcat.go:

package main

import (
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"log"
	"os"

	"github.com/mattn/go-sixel"
)

func main() {
	img, _, err := image.Decode(os.Stdin)
	if err != nil {
		log.Fatalf("Cannot decode image from stdin: %v", err)
	}

	err = sixel.NewEncoder(os.Stdout).Encode(img)
	if err != nil {
		log.Fatalf("Cannot encode image into sixel format: %v", err)
	}
}

在 iTerm2 里运行如下命令,即可显示一个图像文件 a.png

cat a.png | go run imgcat.go
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值