Elytra
Blog编程语言

用 Rust 和 egui 重造 Adobe 全家桶?

从几十 MB、一秒多就安装好的 PhotoCraft 和 FilmCraft 出发,聊聊 AI 重造创作软件的惊讶、egui 即时模式 GUI 的性能与开发体验,以及原生 UI 与 Web UI 的取舍。

最近看到一个颇为夸张的项目:有人借助 AI,用 Rust 重新实现了一系列 Adobe 风格的创作软件。从 Photoshop、Premiere Pro、After Effects,到 Illustrator、Lightroom、Acrobat 和 InDesign,几乎凑齐了一套「Adobe 全家桶」。1

一开始我也只是觉得:AI 编程确实越来越厉害了。但真正让我感到不可思议的,是把软件下载安装到电脑上之后。

PhotoCraft 的安装包在我这里大约只有四五十 MB。我双击安装,几乎一秒多就结束了,快得让我怀疑是不是安装程序崩溃了。没想到再去打开,它真的已经安装好了,窗口能正常启动,工具栏、图层、画布、属性面板也都有模有样。

FilmCraft 同样让我意外:我拿到的版本大约 75 MB,主要就是 GUI 和 CLI 两个可执行文件。一个看起来像 Premiere 的视频编辑器,竟然可以是这么轻巧的东西。

这与我对 Adobe 软件的印象形成了巨大反差:动辄数 GB 的安装内容、漫长的安装和更新过程,以及背后数十年的研发积累。突然出现几套小巧的应用,看上去竟然已经相当像那么回事了。

当然,体积小、安装快,不等于功能和成熟度已经追上 Adobe。它们打包的资源、依赖、插件和功能范围并不相同。但这种反差还是足够让我好奇:它们究竟是怎么实现的?尤其是——那个 UI 到底是怎么做出来的?

1一套用 Rust 写的创作软件

这组项目出自 ArtCraft / storytold,几乎覆盖了整套 Adobe 创作工具:

Craft 项目对应的 Adobe 软件主要用途
PhotoCraftPhotoshop位图编辑、图层、蒙版与 PSD
VectorCraftIllustrator矢量图形、路径与插画
FilmCraftPremiere Pro多轨视频剪辑、调色、音频与导出
EffectCraftAfter Effects动画、关键帧、合成与视觉特效
LightCraftLightroom照片管理与 RAW 调色
PdfCraft(原 PrintCraft)Acrobat ProPDF 阅读、编辑与处理
DesignCraftInDesign页面排版、出版与印刷文档

这些项目定位为对 Adobe 工作流的开源、独立实现,而不是 Adobe 软件的官方移植。其中 PrintCraft 的 GitHub 仓库现已更名为 PdfCraft,旧链接会重定向到新仓库。

它们的共同特点,是以 Rust 作为主要应用语言,按许多独立的 crate 分层组织图像、媒体、文档、编辑命令与用户界面。PhotoCraft 的架构文档甚至明确约束:底层 Engine 不应该依赖 UI 框架,让桌面 GUI、CLI 和自动化接口可以共用同一个引擎。2

1.1两个 EXE:GUI 和 CLI 各做什么?

FilmCraft 安装目录里的两个可执行文件,也很能体现这种架构。filmcraft.exe 是带窗口的编辑器,filmcraft-cli.exe 则是 Command Line Interface(命令行界面),为脚本、批处理和 AI Agent 提供无窗口的操作入口。它们不是「GUI 调用 CLI,CLI 再处理视频」的层级关系,而是两个独立前端,共用同一套 Rust 编辑引擎。所以正常打开 GUI 剪辑视频,不需要另外启动 CLI。3

CLI 可以列出编辑命令、检查工程结构、导入素材、执行时间线操作,甚至在无窗口环境中渲染和导出视频。例如:

filmcraft-cli commands
filmcraft-cli --project example.fcproj inspect
filmcraft-cli --project example.fcproj render --seconds 3 --out frame.png

它还可以启动 MCP Server,供 AI Agent 调用;需要操作已经打开的 GUI 工程时,则可以让 GUI 通过 --control 暴露本地控制端口,再让 CLI 使用 --bridge 连接。这样人工在时间线上点击,和脚本批量执行命令,最终都能走同一个 Engine。CLI 不是视频编辑器的必备后台进程,而是额外的自动化入口。

这部分我反倒比较容易理解。Rust 很适合实现需要大量计算、内存管理和并发处理的底层系统。图像算法、视频编解码、帧缓存、GPU 资源调度……用 Rust 来写,完全符合它作为系统编程语言的定位。

但 UI 呢?

2真正让我意外的,是 egui

我原本以为这种桌面软件的前端大概是 Web 技术:Tauri 包一个 React 界面,Rust 在背后处理图像和视频。毕竟做复杂面板、菜单、拖拽、属性检查器,HTML/CSS 已经有极其丰富的生态。

结果发现,它们的桌面界面主要用的是 egui + eframe,GPU 绘制则集成 wgpu。既不是 Electron,也不是套在 WebView 里的 HTML 页面。2

egui 是 Rust 的即时模式 GUI(Immediate Mode GUI)库,思路与 Dear ImGui 非常接近。熟悉游戏引擎的人大概不会陌生:在一段函数里依次写按钮、滑条和面板,调用时直接描述这一轮 UI 应该长什么样。

例如:

egui::SidePanel::right("layers").show(ctx, |ui| {
    ui.heading("Layers");

    if ui.button("Add Layer").clicked() {
        editor.add_layer();
    }
});

这是一段简化的 egui 风格示例,不是 PhotoCraft 的原始源码。

几行代码就能表达一个面板和它的交互。相比先创建一棵 UI 对象树、维护一堆控件引用,再把事件与状态连接起来,即时模式真的相当直接。

我本来就很喜欢 Dear ImGui。它写调试面板、性能分析器、游戏内工具的体验很舒服;如果再配合代码热重载,调界面几乎是一件很享受的事。

但用 ImGui 风格的东西写 Photoshop、Premiere,以前还真有点难以想象。

2.1它怎么做出那么多复杂面板?

秘密其实并不是「egui 自带 Photoshop」,而是开发者在 egui 之上继续实现了一层编辑器 UI:工具栏、停靠面板、标签页、属性编辑器、时间线、快捷键和主题样式。

FilmCraft 在 crates/ui-egui 中实现了自己的 Docking、Timeline 和 Monitor 等模块;PhotoCraft 还专门写了 UI Design System,去规范颜色、间距、字体、图标以及接近 Photoshop 的交互习惯。4

这也解释了为什么它们第一眼看起来那么像 Adobe:并不是借用了 Adobe 的控件,而是在另一个 UI 框架里重新绘制了相似的工作区和交互结构。

不过亲自上手,细节上的差距还是能感觉到。例如边框、面板控制、拖拽反馈和部分交互手感,都没有 Adobe 那么细致自然。做出「像」的界面,与把一套专业工具的每个角落打磨成熟,终究是两回事。

2.2即时模式是不是每帧都要重建 UI?

这是一个很自然的疑问。传统的 Retained Mode UI,比如 Qt Widgets、WPF、DOM 或 Unity UI Toolkit,会保留控件或视觉树;而 egui 在每次 UI Pass 中,通常会重新执行控件声明、计算布局、处理交互并生成绘制数据。5

但是,「重新描述 UI」不等于「销毁窗口、控件纹理,再从零创建一套 GPU 资源」。字体、纹理和必要的交互状态依然可以缓存。egui 的闭包让布局代码很容易组织,却不会自动让这个闭包变成只在变化时才更新的局部布局缓存。

更重要的是,egui 并不需要在界面静止时一刻不停地运行。它可以由鼠标、键盘、外部任务或 request_repaint() 驱动刷新,也可以延迟安排下一次更新;正在播放动画时,再主动请求持续刷新。6

所以,即时模式的代价主要是每次 UI Pass 要重新做多少工作,而不是「每秒必须白白重建整个应用 60 次」。

2.3Tracy 很流畅,Unity Inspector 却会卡:该怪谁?

提到 Immediate Mode,人们有时会直接联想到性能差,甚至想到 Unity 里某些打开后明显拖慢 Editor 的 Inspector。

但另一个反例是 Tracy:一个使用 Dear ImGui 等技术构建界面的实时性能分析工具。它要展示大量事件、时间线和缩放交互,用起来却可以非常流畅。

我认为这两个体验恰好说明:Immediate Mode 与 Retained Mode,并不能直接作为性能高低的判决书。

Unity Inspector 的开销可能来自属性遍历、序列化、反射、复杂的 Editor 扩展、布局乃至实际绘制;Tracy 的流畅也需要高效的数据结构、可视范围裁剪和渲染策略,而不是光选了 ImGui 就自动获得。

Retained Mode 可以缓存 UI 树、减少某些重复布局,却同样可能因为复杂的状态传播和布局失效而变慢。React 也会重新执行组件函数,不过它的组件执行、DOM 更新和浏览器最终绘制又是不同阶段,不能简单等同于 egui 的每帧绘制。

真正该问的是:每一帧究竟处理了多少可见元素、执行了多少业务逻辑、重新布局了多大范围、向 GPU 提交了多少绘制数据?

2.4如果屏幕有 500 Hz,动画也要重新布局 500 次吗?

以最直接的 egui 写法实现一个面板从左向右滑动的动画:每次动画刷新都重新计算它的位置并运行 UI 布局。如果追求 500 FPS 的 egui 动画,通常就意味着很高频率的 UI Pass。

但我们也可以把布局和最终图像合成拆开:

  • 当面板内容和尺寸不变时,较低频率地更新布局与绘制数据;
  • 在自定义 GPU Compositor 中,按照当前时间更高频率地改变缓存图层的位置、透明度或 Transform;
  • 如果面板尺寸变化造成换行和子控件重新排列,再触发必要的布局更新。

例如 UI 布局只以 20 Hz 更新,GPU 仍以 500 Hz 对缓存的面板图像做位移插值。原理上可行,但不是 egui 默认帮你提供的能力;它需要额外的缓存、合成与输入同步设计,而且 20 Hz 的 UI 状态更新本身也可能带来交互延迟。

这就像游戏引擎里 Simulation 与 Rendering 的解耦:一次更新产生状态,渲染可以在两个状态之间插值。只是一个专门的 GUI 框架未必会直接提供整套方案。

3为什么不选择 Web UI?

其实我对 egui 的惊喜,和对它的疑虑,是同时存在的。

Web UI 在复杂界面开发上有很多实在的优点:HTML/CSS 有成熟的布局能力,React/Vue 有大量第三方组件,浏览器提供开发者工具、字体排版、可访问性支持,以及几乎令人上瘾的 HMR(热模块替换)。

而 egui 的 UI 代码就是 Rust。修改一段界面逻辑,通常需要重新编译、重新运行。可以用 cargo-watch 一类工具自动构建和重启,也能通过动态库等更复杂的架构尝试热重载,但它默认没有 Vite 那样修改组件便立即更新的开发体验。

把这两条路线放在一起,会更清楚:

Rust + eguiRust + Web UI(如 Tauri)
写界面Rust 函数、即时布局HTML/CSS/JS、DOM
与 Rust 引擎交互可以直接调用同进程 API通常需要前后端通信
开发时修改 UI通常重新编译HMR 生态成熟
自定义绘制与 GPU容易与 wgpu 集成可用 Canvas/WebGPU,原生 GPU 共享需要额外架构
样式与第三方组件较依赖自行实现生态非常丰富
用户编写复杂插件面板要先定义宿主 UI 接口可直接利用 Web 技术

不能简单说哪一种一定更快。Tauri 也不是把完整 Chromium 都打进应用:它一般使用系统 WebView,所以同样可以做得很轻;反过来,egui 也并不天然意味着低内存、零布局开销。

从这几个 Craft 仓库的架构看,选择 egui 的好处相当明确:一套 Rust 工具链、直接的函数调用、可复用的桌面/WebAssembly UI,以及和 GPU 编辑画布更统一的运行环境。至于作者当时具体如何权衡 React、Tauri、Qt 等方案,没有完整决策记录就不宜替他编造理由。

3.1那插件怎么办?

我曾经以为,Rust 原生 UI 可能意味着插件必须编译成 Windows DLL、Linux SO 或 macOS 动态库,才能扩展界面。

其实插件格式取决于宿主提供什么 API,不取决于 egui 本身。脚本、WASM、进程间通信、原生动态库,都可以成为扩展机制。

PhotoCraft 就已经支持基于 WebAssembly 的滤镜插件:第三方将计算逻辑编译为 .wasm,宿主在沙箱里执行,并根据参数声明生成 egui 对话框。这不要求插件直接链接宿主的 Rust UI 代码,也更容易跨平台。7

不过,截至本文整理时,它的插件 ABI v1 尚不支持插件自定义 UI 面板。如果希望第三方自由编写完整的属性窗口、富文本界面或可交互图表,WebView + HTML/CSS/JS 的确更有生态优势;egui 则需要另外设计足够完整的 UI 扩展协议。

所以我并不认为原生 UI 必然排斥插件,但想做一个开放的创作者生态,UI 的可扩展性必须从一开始就设计。

4UI 背后,是一整套真正的 Rust 编辑引擎

当然,只有酷似 Adobe 的界面还远远不够。真正令人意外的,是界面背后并不完全是空壳。

可以用这张简化的图理解三套软件的共同思路:

Loading diagram…

PhotoCraft 将图像划分成 256×256 的 Tile,使用 Copy-on-Write 管理像素变化,再通过 CPU/GPU 合成图层。FilmCraft 则有多轨时间线、整数时间基准、帧缓存与媒体管线,部分视频 Codec 甚至自行用 Rust 实现。EffectCraft 进一步把图层合成、关键帧、JavaScript 表达式和 GPU 特效组合起来。2

对我而言,其中最值得借鉴的不是「什么都要自己实现」,而是将 GUI 和 Engine 分开:鼠标拖动、菜单点击、CLI 命令和 AI Agent 调用,都尽可能落到一套共同的编辑命令上。

这样既能保持 UI 灵活,也让底层计算可以被测试、自动化、甚至替换 UI 前端。对于未来想自己做游戏编辑器、Modding 工具或图形创作软件的人,这种结构很有启发。

5小巧,不代表已经超越 Adobe

回到最初的安装体验。我仍然觉得几十 MB 的安装包和几乎一瞬间完成的安装非常惊艳,但不能仅凭体积判断架构优劣。

体积受很多因素影响:是否捆绑大型运行时、素材、字体、预设、模型、插件、第三方组件和兼容性资源;有没有依赖系统已有的能力;是否只实现了部分功能。拿轻量的新项目和积累几十年的完整商业软件比安装体积,本来就不是同一个比赛项目。

实际操作中,Craft 的界面细节、反馈和稳定性仍有不少打磨空间。尤其是复杂媒体、边缘文件、专业插件、跨版本工程兼容,以及那些用了多年才逐渐完善的小交互,都很难用「功能清单里已经有了」来衡量。

做出一个 Photoshop 风格的应用,与真正替代 Photoshop,是两件相差很远的事。

6但它依然改变了我的想象

让我震惊的不是这些项目已经把 Adobe 打败了,而是:过去觉得需要庞大团队、长期积累才能接近的软件,如今已经可以借助 AI 与开源生态,在相对短的周期内把架构和相当多的功能搭建起来。

更出乎我意料的是 UI。我原先会把 Rust 放在「高性能核心和底层算法」的位置,把复杂桌面界面留给 Web、Qt 或其他成熟框架。PhotoCraft 和 FilmCraft 提醒我,Rust + egui 也可以长成一个完整的专业创作软件的样子。它未必是最省事、最灵活的路线,却绝不是只能写几个调试按钮的玩具方案。

AI 让「先做出一个东西」越来越容易,但软件真正昂贵的部分,也许会因此更加清晰:不仅是实现功能,还有交互手感、可靠性、兼容性、长期维护,以及对用户真实工作流程的理解。

至少这次,一次快得让我以为失败了的安装,让我重新认识了 Rust GUI,也重新想象了一遍未来的软件开发。

注释

  1. ArtCraft / storytold,以上七个项目的 GitHub 仓库(见正文表格);PdfCraft 为原 PrintCraft 的现用仓库名称。用于核对项目定位;文中的安装包大小、安装耗时和主观操作感受来自个人体验,并非统一基准测试。 ↩

  2. 项目架构文档:PhotoCraft、FilmCraft、EffectCraft。说明 crate 分层、egui 前端、命令系统、媒体/图像与 GPU 子系统。 ↩ ↩2 ↩3

  3. FilmCraft,GUI Cargo.toml、CLI Cargo.toml、CLI main.rs 及 README。两个 binary 分别依赖同一个 filmcraft-engine;CLI 支持 headless 操作、MCP 和 bridge 到 GUI 控制端口。 ↩

  4. PhotoCraft,UI Design System;FilmCraft,架构文档。分别记录外观交互规范和 Docking/Timeline 等 UI 模块。 ↩

  5. egui 项目官方文档,egui – immediate mode GUI;说明控件声明在 UI Pass 中执行、布局和绘制数据的生成方式。 ↩

  6. egui,Context 文档;包含 request_repaint、request_repaint_after 等刷新机制。更新频率由宿主与动画需求共同决定。 ↩

  7. PhotoCraft,Plug-ins: the WebAssembly plug-in API。记录 WASM 滤镜插件、参数生成的对话框,以及 ABI v1 暂不支持自定义 Panel/UI 插件。 ↩

CONTINUE EXPLORING

沿着这篇文章继续

在地图中查看

On this page