在 WSL 里用 fim 打开图片,窗口直接弹到 Windows 桌面
原创 · 约 22 分钟阅读 · 阅读 --

在 WSL 里用 fim 打开图片,窗口直接弹到 Windows 桌面

作者: Alex Xiang


古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。更完整的更新写在微信公众号「字与码」:工作经历、对新技术的想法,以及这些年走弯路的记录,会不定期发在那里。若觉得博客对你有用,欢迎顺手关注。

前几天在 WSL 里看一张脚本生成的图片,顺手敲了一句:

fim result.png

我原来以为它要么在终端里糊一坨字符画,要么因为没有 framebuffer 直接报错。结果它在 Windows 桌面上弹出了一个图形窗口,和普通 Windows 程序一样可以拖动、Alt+Tab、和别的窗口并排。

这个体验挺容易被忽略。现在的 WSL 已经把 Linux GUI 做得太自然了,自然到你会忘记它以前不是这样的。

WSL 里的 Linux 图片查看窗口显示在 Windows 桌面

这篇不讲“如何把 WSL 配到花里胡哨”。只从 fim 这个小工具开始,记录一下现在 WSL 显示图片和跑图形程序到底是怎么回事,哪些地方真的好用,哪些地方最好别折腾过头。

先确认你的 WSLg 是好的

今天在 Windows 11,或者较新的 Windows 10 + WSL2 环境里,Linux GUI 程序能直接显示到宿主 Windows 桌面,主要靠的是 WSLg。

微软文档里说得很直接:WSL 支持运行 X11 和 Wayland Linux GUI 应用,并且能和 Windows 桌面集成,比如从开始菜单启动、固定到任务栏、Alt+Tab 切换、跨 Windows/Linux 剪贴板复制粘贴。这个能力依赖 WSL2,WSL1 不支持。

如果是新机器,管理员 PowerShell 里一般一条命令就够:

wsl --install

如果已经装过 WSL,先更新:

wsl --update
wsl --shutdown

然后进 Ubuntu 做一个最朴素的测试:

sudo apt update
sudo apt install x11-apps -y
xeyes

如果屏幕上出现那对老派的眼睛,说明最基本的图形链路通了。这个测试比盯着环境变量看半天更实在。

当然,也可以顺手看一下:

echo "$WAYLAND_DISPLAY"
echo "$DISPLAY"
echo "$PULSE_SERVER"
ls -la /mnt/wslg

正常情况下,WSLg 会把 Wayland、X11、音频相关的 socket 放进你的 Linux 发行版。你不需要自己启动一个 X Server,也不需要照着老教程手动写 DISPLAY=:0。很多旧文章是给没有 WSLg 的年代准备的,今天照抄反而容易把默认配置弄坏。

它不是“把一个 Linux 桌面远程过来”

这点很关键。

WSLg 不是在 Windows 里开一个完整 Linux 桌面,然后把所有应用塞进去。它更像是给 Linux 图形应用准备了一条窗口投递通道。

大致链路是这样:

Linux 应用启动后,现代程序优先走 Wayland。传统 X11 程序走 XWayland。中间的 compositor 是 Weston。Weston 再通过 RDP 后端,把单个应用窗口投到 Windows 桌面。微软在 WSLg 架构文章里提过,他们是 Wayland-first,同时通过 XWayland 兼容大量旧 X11 应用。WSLg 项目文档里也写到,WSLGd 会启动 Weston、XWayland、PulseAudio,并和 Windows 宿主建立 RDP 连接。

所以你看到的不是一个“虚拟机桌面窗口”,而是一个个 Linux 应用窗口混在 Windows 桌面里。

运行 xeyes,出来一个小窗口。
运行 gedit,出来一个编辑器。
运行 fim result.png,出来一个图片窗口。

这也是现在 WSL 图形体验比早年手工配 VcXsrv 省心很多的原因。过去你得考虑 X Server 有没有开、防火墙放不放、DISPLAY 写多少、剪贴板通不通。现在大部分时候不用管。

WSLg 让 Linux GUI 窗口自然混入 Windows 工作台

fim 到底是什么

fim 的全名是 Fbi IMproved。名字里这个 fbi 不是那个机构,而是 Linux framebuffer image viewer。

它确实有很强的 framebuffer 传统,但现在不只是 framebuffer 查看器。Debian man page 把它叫作显示图片的“swiss army knife”:可以用不同图形设备显示图片,支持键盘操作、脚本、EXIF、自动缩放、从标准输入读取图片等。它会根据当前环境选择合适的输出设备;有图形环境时可以走 SDL/GTK,纯文本或远程场景可以走 ASCII driver,裸 Linux 控制台可以走 framebuffer。

这也是 WSL 里容易误解的地方。

WSL 通常没有传统 Linux 控制台里的 /dev/fb0。你在 WSLg 下用 fim 弹出窗口,并不是 Windows 给它虚拟了一个 framebuffer,而是 fim 选择了图形后端,最后经过 WSLg 显示到了 Windows 桌面。

安装:

sudo apt update
sudo apt install fim -y

打开单张图片:

fim result.png

打开一个目录:

fim ./screenshots/

自动缩放:

fim -a result.png

配合管道看一批图片:

find ./frames -name '*.png' | sort | fim -

从标准输入读图片:

cat result.png | fim --image-from-stdin

fim 的界面不花哨,操作也偏键盘。它不像 Windows 照片查看器那样面向普通用户,而更像图片版的 less:临时看一眼、从命令行打开、从管道接数据、看完就回终端。

这恰好适合 WSL 的工作方式。

我最常用的场景:Linux 里算,Windows 上看

比如脚本生成了一张图:

python render_report.py --out report.png
fim -a report.png

或者批量处理图片:

mkdir -p out
python process_images.py --input ./raw --output ./out
fim ./out

再比如画一张 Matplotlib 图:

import matplotlib.pyplot as plt

days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
values = [12, 19, 15, 23, 18]

plt.figure(figsize=(8, 4))
plt.plot(days, values, marker="o")
plt.tight_layout()
plt.savefig("chart.png", dpi=160)
python chart.py
fim chart.png

这事的价值不在“Windows 能不能看图片”。Windows 当然能看。真正舒服的是不用离开当前上下文。

依赖在 WSL 里,脚本在 WSL 里,文件也在 WSL 的 ext4 文件系统里。生成完结果,不用复制到 /mnt/c/Users/...,不用起一个临时 Web 服务,也不用打开 Notebook,只要 fim 一下。

我觉得这对几类工作特别实用:

  • 图像处理:OpenCV 前处理、检测框、OCR 中间结果;
  • 数据可视化:脚本生成的图表、报表截图;
  • 自动化测试:Playwright 或 Selenium 截图;
  • 地图和渲染:瓦片、热力图、布局预览;
  • 文档处理:PDF 转图片、图片压缩前后对比。

在 WSL 中开发图像应用并在 Windows 桌面预览结果

直接开发 Linux 图形程序也可以

只看图片用 fim 就够了。但 WSLg 更大的价值,是你可以在 Linux 里开发图形程序,窗口直接显示到 Windows。

最简单的是 OpenCV:

sudo apt install python3-opencv -y
import cv2

img = cv2.imread("sample.jpg")
cv2.imshow("preview", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在 WSLg 下,cv2.imshow 会打开一个图形窗口。调视觉算法时很方便,尤其是看边缘检测、二值化、检测框、裁剪结果这种中间图。

Tkinter 也能用:

sudo apt install python3-tk -y
import tkinter as tk

root = tk.Tk()
root.title("WSL GUI")
tk.Label(root, text="Hello from Linux").pack(padx=40, pady=30)
root.mainloop()

要做更像产品的界面,可以用 Qt:

python -m venv .venv
source .venv/bin/activate
pip install PySide6
from PySide6.QtWidgets import QApplication, QLabel

app = QApplication([])
label = QLabel("Linux GUI running on Windows via WSLg")
label.resize(420, 120)
label.show()
app.exec()

这类程序最终如果要发布给 Windows 用户,当然还要按 Windows 平台重新测试和打包。但开发早期,尤其核心依赖本来就在 Linux 生态里时,在 WSL 里直接跑 GUI 很省事。

我的边界感是:WSLg 适合“跑单个 Linux GUI 应用”,不适合把 WSL 当完整 Linux 桌面来用。微软文档也提醒过,WSL GUI 支持不是完整桌面体验。你可以折腾 GNOME、KDE,但日常没必要。

出问题时怎么排查

如果 fim image.png 没弹窗,我一般按这个顺序排:

wsl --version
wsl --update
wsl --shutdown

重新进 Linux 后,先跑:

sudo apt install x11-apps -y
xeyes

如果 xeyes 都不出来,先别怀疑 fim,图形基础链路就没通。

继续看:

echo "$DISPLAY"
echo "$WAYLAND_DISPLAY"
ls -la /mnt/wslg

如果 xeyes 能出来,fim 不行,再看 fim 的输出设备和依赖:

fim --output-device
ldd "$(command -v fim)" | grep -Ei 'sdl|gtk|x11|wayland'

也可以装一个更传统的 X11 图片查看器交叉验证:

sudo apt install feh -y
feh image.png

feh 很轻,行为也简单。它不像 fim 那么偏管道和键盘,但做 X11 图片查看器非常可靠。

那些老 X 小程序还有没有价值

xeyes 看起来像玩具,但它一直是很好的烟雾测试:窗口能不能出来、鼠标事件有没有传进去、XWayland 是否正常,一眼就知道。

除了 xeyes,我觉得下面这些小工具还真能留在日常工具箱里:

工具安装包用途我的判断
xeyesx11-apps测试 X11 和鼠标事件不替代任何东西,诊断用
xclockx11-apps小时钟、测试窗口刷新偶尔有用
xcalcx11-apps轻量计算器临时可用
xtermxterm传统 X 终端不建议替代 Windows Terminal
xevx11-utils查看键盘、鼠标、窗口事件GUI 调试很好用
xpropx11-utils查看窗口属性调 X11 程序时有用
xwininfox11-utils查看窗口尺寸和位置截图、自动化调试有用
fehfeh快速图片查看能替代一部分图片查看场景
meldmeld图形 diff/merge很适合 Linux 项目
gimpgimp图像编辑完整工具,按需装
wiresharkwireshark抓包分析Linux 网络调试时很方便

我不建议为了“替代 Windows 程序”而替代。更舒服的方式是:Windows 负责桌面体验,Linux 工具在它擅长的地方出现。

比如终端我还是用 Windows Terminal;图片如果是 Linux 脚本刚生成的,就用 fimfeh;diff 如果和 Linux 项目有关,就用 meld;网络抓包如果跑在 Linux 环境里,就用 Wireshark。

传统 X11 小工具也可以在 WSLg 中作为日常工作台的一部分

fim、feh、Windows 图片查看器怎么选

我的选择很简单:

  • 图片在 Windows 文件夹里,直接双击;
  • 图片是 Linux 脚本生成的,用 fim -a image.png
  • 想快速看一个目录,用 fim ./dir/feh ./dir/
  • 想从管道接文件列表,用 find ... | fim -
  • 想编辑图片,用 GIMP 或 Windows 工具;
  • 想写 GUI 程序,用 OpenCV、Tkinter、Qt、GTK、SDL 这些正经框架。

fim 的价值不是界面漂亮,而是它站在命令行和图形窗口之间。它把“生成图片、看一眼、继续改脚本”这条路径变短了。

小结

fim result.png 能在 Windows 桌面上弹出窗口,看起来只是一个小技巧。

但它背后其实是一个工作流变化:Linux 不再只是 Windows 里的黑框,也不必变成一台完整虚拟机。它在需要图形界面的时候,把窗口交给 Windows;在需要包管理、脚本、编译和数据处理的时候,继续保持 Linux 的样子。

这就是 WSLg 最舒服的地方。

不是为了炫耀 Linux GUI 也能跑在 Windows 上,而是为了少打断自己。

写脚本,出图,预览,继续改。
跑工具,弹窗口,关掉,回终端。

参考资料: