PhotoCraft 项目推荐:用 39 万行纯 Rust 从零重写 Photoshop,还把一个编辑器做成了 700 条命令
PhotoCraft(storytold/photocraft)是 ArtCraft 团队用纯 Rust 从零实现(clean-room reimplementation)的分层图像编辑器,对标的直接目标就是 Adobe Photoshop。截至本文发布,项目拥有 47.5k stars、7.6k forks、1,237 个 open issues,以 100% Rust 写成,主仓库按 Apache-2.0 / MIT 双许可(GitHub 识别为 Apache-2.0)开源,最新版本 v0.7.0(2026-10-11 发布,此前 10 月内已连发 v0.2/v0.3/v0.5/v0.6/v0.7 五个版本)。
这不是又一个"轻量修图小工具"。它的 README 开门见山写着:layers、masks、adjustment layers、layer styles、type、vectors、brushes,以及真正的 PSD 文件——67 个工具、27 种 Photoshop 混合模式、4 种色彩模型 × 4 种位深、628/628 个 Photoshop 菜单项全部接上了命令。
而比"功能清单长"更值得说的是它的工程方法:25 个库 crate、约 393,000 行 Rust、1,020 个文件、5,460 个 #[test] 函数(README 另有"1,700 多个测试"的口径,指完整测试条目)、1,004 个已合并 PR,一个把"从头写一个 Photoshop"当成软件工程问题来做的项目。这篇推荐就来拆一拆:一个人(加上 AI 助手与开源社区)到底怎么从零造出一个图像编辑器的引擎。
它是什么:一个"引擎优先、命令驱动"的原生编辑器
先看它的产品定位。PhotoCraft 属于 ArtCraft 团队的 “Crafting Apps” 家族(兄弟项目有 VectorCraft 矢量、FilmCraft 视频、LightCraft RAW、PdfCraft PDF、DesignCraft 排版等),共同约定是:clean-room、纯 Rust、原生跨平台(macOS / Windows / Linux / FreeBSD)、通过 WebAssembly 跑进浏览器、且完全可被 AI Agent 驱动。
它的能力面覆盖得相当完整:
- 图层系统:分组、剪贴蒙版、像素/矢量蒙版、填充图层、调整图层、带智能滤镜的无损智能对象、多图层对齐/分布/链接、alpha 通道与快速蒙版、27 种 Photoshop 混合模式 + 6 种 Paint.NET 变体;
- 16 种调整图层:曲线(支持分通道)、色阶(带实时直方图)、自然饱和度、黑白、通道混合器、渐变映射、照片滤镜、可选颜色、颜色查找(
.cube/.3dl/.look)等; - 图层样式:投影、内阴影、外/内发光、斜面和浮雕、缎面、描边、颜色/渐变/图案叠加,可作用于任意图层(含文字图层);
- 真实画笔引擎:形状动态、散布、纹理、双重画笔、颜色动态、传递、笔尖姿态、湿边、构建、平滑(含 Pulled String),由压感/倾斜/旋转/方向驱动;
- 滤镜即预览:高斯/动感/径向/镜头/表面模糊、模糊画廊(倾斜偏移、光圈、场景、旋转、路径)、锐化、降噪、扭曲(旋转扭曲、波浪、波纹、置换、切变、锯齿)、像素化、风格化、渲染——每个对话框都能在画布上按选区实时预览;
- 色彩与位深:RGB / 灰度 / CMYK / Lab,8 / 16 / 32 位每通道——位深和色彩模型是运行时数据,所以每个工具都能在所有位深下工作;
- 格式广度:PSD/PSB、分层 TIFF、PDN3、OpenRaster、SVG、PNG/JPEG/WebP/GIF/BMP/TGA/ICO/QOI/PNM/OpenEXR/Radiance HDR/FITS,以及只读的 HEIC 与 Affinity 文档(
.af/.afphoto/.afdesign/.afpub)。
但真正让它从"功能列表"变成"值得推荐"的,是下面三件事。
起源故事:为什么放着现成的轮子不坐,偏要手搓
PhotoCraft 的故事里最有意思的,是它对同行的冷酷复盘。
在主仓库的架构文档 docs/architecture.md 里,作者专门写了一节叫 “Avoiding GIMP’s hole”(避开 GIMP 的坑),把 GIMP 二十多年的技术债摊开来讲:
- GIMP 最初的内核把每通道 8 位硬编码进瓦片(tile)结构,想要高位深就得另起一个引擎 GEGL——GEGL 大约 2000 年开工,2008 年作为可选组件引入,直到 GIMP 2.10(2018)才真正完成移植,官方说法是"六年工作的结果";
- Photoshop 大约 1994 年就有了调整图层(调整层,非破坏式编辑);而 GIMP 直到 **3.0(2025 年 3 月)**才有非破坏式滤镜,到 **3.2(2026 年 3 月)**才有非破坏式图层类型;
- GIMP 3.x 内部仍然是"100% RGB 编辑器",CMYK 只存在于导出和软打样;
- PSD 导入仍然有损:Photoshop 的调整图层与多数图层样式无法忠实带回,文字常常要重新排。
作者的结论一句话:
根本原因在于——像素位深、色彩模型、“图层就是一个像素缓冲区"这些基本属性,被当成硬编码的假设写进了内核,而不是当作数据。
这个判断直接决定了 PhotoCraft 的第一条设计规则:从一开始就让这些属性成为运行时数据。下表摘自它的架构文档,每一条都是"现在很便宜、将来会逼你重写一切"的决定:
| 属性 | 规则 | 落到的 crate |
|---|---|---|
| 位深 | 每个 surface 携带运行时 PixelFormat { depth: U8|U16|F16|F32, model, alpha };算法写成对 Sample trait 泛型、按位深单态化;任何公开引擎 API 里都不出现 u8 像素类型 | raster, color, algo |
| 色彩模型 | ColorMode(RGB/灰度/CMYK/Lab/索引/位图 + 多通道/专色)从第一天就在 doc 里;通道数动态(1–N + alpha + 专色) | doc, raster, psd |
| 色彩管理 | 每个文档都有 ICC profile;合成器接收工作空间描述符;显示变换是独立的最后一级 | color, compose |
| 非破坏性 | LayerContent 是一个枚举,v1 就包含 Adjustment / Fill / Text / Shape / Smart;合成器评估的是**图(graph)**而不是一堆扁平缓冲区 | doc, compose |
| 尺寸 | 瓦片式稀疏存储走 TileStore trait,64 位坐标支撑 PSB 级画布(300k × 300k) | raster |
| UI 工具包 | 内核永不依赖 UI 工具包,UI 可以被换掉而不动引擎 | 分层规则 |
最后一句是它的检验标准:“加一种 64 位浮点、一种新色彩模型、或一种新文件格式,应该只碰一个叶子 crate,而不是地基。”
技术亮点:一个编辑器引擎的四道硬功夫
亮点一:分层 crate 架构 + “一切皆命令”
PhotoCraft 的工作区是 25 个库 crate,按层组织,依赖方向由构建时强制检查(cargo xtask layers):
L0 geom cms color raster # 几何、纯 Rust ICC、像素格式+混合数学、写时复制瓦片
L0 psd codecs tablet # 独立格式 crate,不依赖工作区;tablet 是唯一允许 unsafe 的 crate
L1 doc # 文档模型:图层树、蒙版、调整、效果、智能对象(纯数据 + serde)
L2 ops paint algo text vector # 历史/事务、画笔引擎、成像算法、排版、路径与形状
L3 compose gpu format # CPU 合成器(oracle)、wgpu 合成器、原生 .pcraft 格式
L4 io plugins # 文档 ↔ PSD/扁平静态格式;沙箱化 WebAssembly 插件
L5 engine # Session + 命令注册表(每个动作都是一条命令)
L6 ui-egui automation # 薄薄的 egui 外壳;MCP server
规则很硬:crate 只能依赖更低的层;psd/codecs/cms 不依赖工作区任何东西;ui-egui 以下不许出现 egui/eframe/winit/rfd。
而贯穿所有层的核心设计是 “Everything is a command”(一切皆命令):每个用户可见动作都有一个稳定的 CommandId(例如 filter.blur.gaussianBlur)与带类型的可序列化参数,注册在 crates/engine 里,约 700 条命令。菜单、命令面板(⌘F)、快捷键、录制回放的动作(Actions/macros)、CLI、JSON 控制通道、MCP server、插件——全部派发同一套命令。
于是"Agent 可驱动"不是事后加的功能,而是架构的必然结果:
# 无头模式:打开 → 智能锐化 → 加一个曲线调整层 → 存成 PNG
photocraft-cli run wave.psd \
--cmd filter.sharpen.smartSharpen --params '{"amount":80}' \
--cmd layer.newAdjustmentLayer.curves --params '{"points":[[0,0],[64,48],[192,212],[255,255]]}' \
--out wave-final.png
# 把同一份动作列表批量套到一整个目录
photocraft-cli batch --actions grade.json --in ./raw --out ./graded
# 让 Agent 通过 MCP 直接开图干活
photocraft-cli mcp
README 里所有截图——对《神奈川冲浪里》《印象·日出》《Earthrise》等公有领域画作做的编辑——都是通过这个控制通道离屏渲染出来的,而不是手工截图摆拍。这一点很能说明"引擎优先、无头优先"是不是真做到了。
亮点二:双合成器 + 写时复制瓦片——把"正确"和"快"分开验证
图像编辑器的性能包袱几乎全在合成(compositing)这一环:任何一次拖动图层、改不透明度、切混合模式,都要重新算一遍像素。PhotoCraft 的解法是两个合成器:
- CPU 合成器(
compose):Rust + rayon 实现,确定性、参考实现,充当 oracle(判据); - wgpu 合成器(
gpu):把画布放上 GPU(后端着 Metal / Vulkan / DX12 / WebGPU),目标是与 CPU 版误差 ≤ 1/255。
两个合成器互相测试——GPU 版不是"另一份实现”,而是"必须向 CPU 参考实现看齐的实现"。这条设计把"性能优化会不会算错"的验证问题变成了一条数值断言。同时,参数结构体是同一份 #[repr(C)] + bytemuck::Pod 定义,CPU 与 WGSL 共用,杜绝了"同一算法在两种语言里各写一份、然后手工同步"的经典灾难。
存储层则是 256×256 写时复制(copy-on-write)瓦片,像素数据放在 Arc 共享的瓦片里:
文档 = 图层树
└─ 每图层 = 稀疏瓦片表 { (tile_x, tile_y) -> Arc<Tile(256×256)> }
├─ 取快照:只复制瓦片指针 → O(图层数),与画布尺寸无关
├─ 画一笔:只克隆被触及的那几块瓦片(其余 Arc 共享)
└─ 撤销:把旧瓦片指针换回来——天然就是一份历史
好处是连锁性的:快照开销与画布大小无关,于是撤销、后台任务、自动保存、UI 读取都变成廉价的、无锁的操作;超大画布(PSB 尺度)也不会因为"一份完整副本"而爆内存;效果图(effect maps)可以按图层状态缓存,改一个参数只失效相关缓存。
顺带一提,低层算法也做了扎实的工程:大半径模糊使用跨所有核心的 running-sum box 多趟近似——README 给的数字是"3.6 MP 上半径 180 的高斯模糊不到一秒"。
亮点三:真实的 PSD——用"语料库 + 渲染判据"来定义兼容性
对任何想替代 Photoshop 的项目,PSD 才是真门槛:格式文档公开,但"读进来能打开"和"读进来像素长得跟 Photoshop 一样"之间隔着巨大的鸿沟。PhotoCraft 把 PSD/PSB 支持做成独立的 crate(psd),依据 Adobe 公开规范从零编写,并用一个真实文件语料库来验收,README 给出了相当克制的数字:
- 忠实往返:打开再保存后,渲染结果与原始文件一致的比例是 psd-tools 测试集 309 个文件中的 307 个,自有混合语料 170 个中的 169 个;尚未建模的内容(raw blocks、descriptors、extras)原样搬运而不是丢弃;
- 像素对得上:用合成 oracle 把自家渲染结果与 Photoshop 的合并图像逐像素比对,覆盖渐变色插值(Classic / Perceptual / Linear)、图层效果、形状描边、剪贴与填充不透明度;
- 大文档:PSB、16/32 位文件、CMYK 与 Lab 文档都能原生打开。
读者如果手上有 PSD 相关经历,会明白这份"307/309"的口径有多老实——它明说了重存的文件与源文件不是逐字节相同(PhotoCraft 会重写图像资源、图层记录和合成图),只有独立于文档模型的 photocraft-psd crate 才能对着语料做到逐字节复现。把一个很难的兼容性目标拆成"渲染一致"和"逐字节一致"两个可测量的档位,比一句"全面兼容 PSD"诚实得多,也更有工程价值。
亮点四:同一份 Rust,编译到浏览器;以及一个敢给自己打分的项目
两个"额外加分项"值得单拎出来。
其一,整个引擎与 UI 能编译到 WebAssembly——桌面端是原生 egui/eframe on wgpu(明确拒绝 Tauri / Electron / webview 外壳,源码里写着 “No JavaScript or TypeScript”),而浏览器版是把同一份 Rust 用 trunk + wasm-bindgen 编出来的,官方还给了可直接自托管的静态站压缩包。没有第二套前端代码,就没有第二份 bug。
其二,这个项目把自我评估做到了罕见的程度。ROADMAP.md 与 docs/scorecard.md 把对标 Photoshop 2026 的进度拆成维度公开打分,包括很多团队不愿意写出来的数字:
功能广度 ~76% 菜单 628/628、工具 56/68、面板 30/35
可投入实际工作 ~45%(40–50%)
对普通专业用户 ~43%
只用到核心功能 ~61%
性能 25%(25 条预算中满足 3 条)
稳定性 45%
以及一句很关键的坦白:“PSD 的完整往返在早期 alpha 阶段还不被 Photoshop 可靠接受(#1281、#2469),但先把数字和问题摆出来。” README 的 Status 提示也写得很清楚——它现在还不是能替代 Photoshop 做日常工作流的产品,缺口在 AI/生成式功能、15 个缺失工具、排版与专业工作流深度、插件兼容性。一个 47.5k star 的项目敢在首页写"我还不合格",这种坦率本身就是技术可信度的一部分。
优点:为什么值得关注
1. 一个真实可读的"大型 Rust 工程范本"
25 个分层 crate、约 39.3 万行 Rust、5,460 个测试、构建期强制分层、泛型位深、CPU/GPU 双实现互测——它把很多团队只在架构文档里画的概念真正落地成代码,而且是可 clone 可 cargo test 的。想学 Rust 大型工程组织、GPU 计算、图像管线的,这是一个少见的公开样本。
2. 对标的是"另一个产品",不是"另一个工具"
它明确以 Adobe Photoshop 2026 为目标应用,用菜单清单、工具计数、性能预算、像素 oracle 去度量差距。这种"以竞品为规格书"的做法,让它的路线图可验证——ROADMAP.md 中标着它已合并 1,004 个 PR,并据此校准剩余工作量(到 beta 约 1,100–1,800 小时)。
3. 对 Agent 是真友好,不是加个 MCP 就完事 “一切皆命令"从引擎层做起,UI/CLI/JSON 控制通道/MCP 共享同一套 CommandId 与参数;还有仅绑定 loopback、需鉴权的控制服务器用于读取 UI 状态、模拟指针事件、离屏截图。想让 AI 帮你批量修图的场景,它的地基是对的。
4. 跨平台与浏览器全覆盖 macOS(含 universal + 公证的 CLI)、Windows(x64/arm64/x86,安装包代码签名)、Linux(AppImage/Flatpak/deb/rpm/tarball,含 aarch64 与 riscv64)、FreeBSD,外加 WebAssembly 静态站——一个开源项目给到这个分发广度,维护成本是实打实的。
5. 干净的出身 clean-room:只研究他人产品的行为,不复制专有代码(连"以可读源码形式发布"的 Rust/WGSL/C++/JS 也不抄),规格来自公开文档(Adobe PSD spec、ISO/ICC)、学术论文(PatchMatch、Poisson blending、ARAP)与实测行为。
注意事项:需要冷静看待的地方
1. 明确处于早期 alpha,别拿它当 Photoshop 用 这是官方自己反复强调的:核心工作流能端到端跑通并保存重开,但 0.5/0.6 版本的用户已经提了 579 个 issue,25 条性能预算里 22 条未达标。README 直言 “it is not yet a Photoshop replacement for daily professional work”。日常生产先别切。
2. 性能是当前最大的短板 拖动带图层样式的图层 p50 321ms(目标 ≤25ms)、改不透明度 276ms、粘贴 12MP 图层 p50 1232ms、内容感知缩放 24MP 用了 954s(目标 ≤3000ms)——这些数字它全部公开。流畅度是目前最明显的体验缺口,也正好是它自己排在首位的优化方向(性能维度仅 25% 达标)。
3. PSD 交换仍有阻断性缺口
重存的 PSD 目前还不能被 Photoshop 可靠接受(#1281、#2469)。如果你的流程必须与 Photoshop / 设计团队互传 PSD,这是硬约束;.psd 相关的所有权重问题在它的 docs/gaps.md 里都编了号。
4. 一个 2026-09-30 才创刊的年轻项目,节奏极快 仓库创建于 2026-09-30,两周内连发五个版本,功能与 CLI 参数仍在快速演进。好处是响应快(1,237 个 open issues 说明社区活跃),代价是升级可能遇到破坏性变更,接口稳定性要等 beta。
5. 环境与细节上的已知坑 Wayland 下文件拖放不能用(上游 winit 0.30 缺 Wayland DnD,官方给了 XWayland 规避方法);AVIF 只能写、JPEG XL 不支持、Affinity 只能读;部分设置项目前"改了没反应”(154 项里有 30 项)。这些都在文档里标了。
6. 构建门槛
从源码跑需要 Rust 工具链、cargo test --workspace 覆盖 5,460 个 #[test];网页版自托管要 Docker 或 trunk。想"拉下来改两行"的轻量读者要有心理准备——这是一个约 39 万行的工程。
适合谁
- Rust 工程学习者与架构爱好者:想看看"分层 crate + 构建期强制依赖 + 泛型位深 + CPU/GPU 双实现互测"在真实大项目里怎么落地——这可能是当下最完整的公开样本之一;
- 图像/图形管线开发者:写时复制瓦片、GPU 3D LUT 色彩变换、running-sum 大半径模糊、合成 oracle 验证、PSD 解析——每一块都能拆出来单独读;
- 想用 Agent 批量处理图片的团队:命令引擎 + CLI batch + MCP + 离屏截图控制通道,“让模型驱动一个真编辑器"这件事它的地基是为你铺的;
- 被订阅制/闭源劝退的创作者与自托管玩家:免费、开源、离线、跨平台、能干真活的替代品,值得装一个 v0.7.0 跟踪它的迭代节奏;
- 开源 Photoshop 替代方案的评估者:想知道"重写一个 Photoshop"到底要多少工作量、卡在哪——它的
ROADMAP.md、docs/gaps.md、docs/scorecard.md是一份罕见的公开工程量清单; - 早期采用者:项目两周内连发五版、社区活跃、方向明确,越早切入越容易把自己的工作流需求推进它的缺口列表。
项目地址:storytold/photocraft | 架构文档:docs/architecture.md | 路线图:ROADMAP.md | 评分卡:docs/scorecard.md | 测试语料:photocraft-corpus | 同族项目:ArtCraft
PSD 格式公开了三十年,“能从零写一个 Photoshop"的项目却始终稀少——不是因为它不难,而是因为它需要把位深、色彩模型、非破坏性这些地基级属性从一开始就当成数据、而不是假设。PhotoCraft 用两周五个版本的节奏,加上一套连自己短板都公开打分的工程方法,给这件事写下了一份目前最诚实的答案。它现在还不合格做你的日常主力,但它已经值得被放进收藏夹,并且值得被读一遍源码。