☰
实测踩坑:把复杂 PSD 拖进 Compositor,文本图层和智能对象直接翻车?
2026/10/10 15:49:13 网站建设 项目流程

实测踩坑:把复杂 PSD 拖进 Compositor,文本图层和智能对象直接翻车?

【免费下载链接】CompositorThe Photoshop alternative for Mac项目地址: https://gitcode.com/gh_mirrors/compos/Compositor

Compositor 是 2026 年社区讨论度最高的 macOS 开源 Photoshop 替代品之一:MIT 协议、SwiftUI + Metal/C 混合架构、对标 PS 核心工作流,连快捷键都照搬。社区文章一边夸它"图层、蒙版、混合模式全面保真",一边也有人吐槽"复杂 PSD 打不开、是毛坯房"。这两种说法其实都对——差别只在于你拖进去的是什么样的 PSD。

本文不站在宣传口径上复述功能列表,而是直接打开仓库源码,把PSDReader→PSDDocumentBuilder→PSDConversionSheet这条导入管线逐层拆开:看转换报告是怎么在"执行前"出现的,看文件夹、蒙版、混合模式凭什么活下来,看文本图层和智能对象又是怎样一步步变成死像素的,最后给出一份可直接执行的转换前检查清单。

导入安全流程:先显示转换报告,再执行导入

先说结论:Compositor 的 PSD 导入是"先报告、后执行"的两段式流程,任何栅格化、降级或裁剪都会在落盘前摆到你面前,你点了确认才会写进文档。

整条链路的入口在 Compositor/Document/EditorSession.swift 的drainImports():检测到8BPS魔数(Compositor/IO/PSD/PSDReader.swift 中的PSDReader.matches)后,先调用beginPSDReading把报告面板挂起来,再异步解析文件:

beginPSDReading(title: "Open “\(url.lastPathComponent)”?", confirmTitle: "Import") let parsed = try await ImageImporter.shared.loadPhotoshop(url, remainingPixels: ...) let assets = try await ImageImporter.shared.photoshopAssets(parsed) imported = try PSDDocumentBuilder.makeImport(parsed, assets: assets) if !(await finishPSDReading(imported.conversions)) { continue } try insertPhotoshop(imported, named: ...)

关键在beginPSDReading的实现:它在文件还没读完时就把面板以isReading: true状态挂上去,文案是 "Reading the file to see what needs converting."。这是刻意的设计——注释写得很直白:"Puts the sheet up before the file is read, so a big PSD doesn't leave the click unanswered." 大 PSD 解析可能要好几秒,先把点击"接住",读完之后才把转换清单填进去(Compositor/Document/EditorSession.swift)。

真正承载这份清单的是 Compositor/UI/PSDConversionSheet.swift 里的PSDConversionSheet,每一条转换记录都带图层名和说明:

Text(request.isReading ? "Reading the file to see what needs converting." : "Compositor will convert these Photoshop features. Nothing is applied until you continue.")

"Nothing is applied until you continue"——这句不是营销话术,是字面意义上的真:finishPSDReading返回false(取消)时直接continue,insertPhotoshop根本不会执行;而每次导入整体包在beginEdit("Import Photoshop File")/endEdit()里,是一笔可撤销的历史事务。换句话说,点 Cancel 是零副作用的。

还有一个细节值得注意:如果解析出的转换清单为空(conversions.isEmpty),面板会直接消失、正常导入;只有纯背景、无图层记录的 PSD(PS 里只合并过图像的文档)走flattenedPhotoshop路径,作为单图层整图读入。

文件夹、蒙版、混合模式保住了,文本与智能对象被栅格化

先看"活下来"的部分,因为这才衬得出后面翻车的分量。

文件夹(图层组)完整重建。PSDReader解析lsct/lsdk附加信息得到 section 标记,assemble里按 PS 的存储顺序(type 3 分隔符、子图层、type 1/2 文件夹)重建父子树:文件夹本身没有图像,bounds等于整个画布,文件夹自己的 opacity 会乘进内部每个图层(PSDDocumentBuilder 注释:"just as Photoshop's group opacity does"),非 pass-through 的组混合模式会降级并明确报告。

图层蒙版保真。PSD 的-2通道解出蒙版灰阶,maskOnLayerGrid把 PS 只存的"非默认值补丁"按文档坐标放回图层像素网格,蒙版的 enabled / linked / default 值全部保留。蒙版解析失败才追加 "couldn't be converted to 8-bit grayscale and was skipped" 的转换记录。

混合模式按 PS 顺序全套映射。Compositor/IO/PSD/PSDTypes.swift 的LayerBlendMode.fromPSD覆盖 24 种模式,注释里特别说明了三个刻意缺席的名字——Dissolve、Darker Color、Lighter Color——"Compositor has no equivalent, so they fall through to Normal and say so in the conversion report",不支持的混合模式会以 "will be applied as Normal" 的形式出现在报告里,绝不静默处理。

调整图层参数级解析。PSDAdjustments能从levl(Levels)、curv(Curves)、hue2(Hue/Saturation)块里还原出四通道色阶、曲线点表和色带参数,导入后仍是可编辑调整层;17 种调整键之外的类型则直接跳过并报告。作为对照,下面这张面板就是你导入一个含 Hue/Saturation 调整层的 PSD 后能拿到的编辑能力:

简单形状与简单文本也可编辑。矩形/椭圆 + 纯色填充(vmsk/vogk/SoCo)映射为活的形状图层;TySh块能解析出字体、字号、颜色、对齐、字距、行距的文本图层,导入后还可以继续输入。

而文本图层和智能对象,就是这场导入里最典型的"翻车位"。

翻车现场复盘:哪些 PSD 千万别直接拖进来

文本图层:能看、不能改,栅格化而不自知

PSD 文本层永远自带一份栅格像素,所以"翻车"不是视觉上消失,而是可编辑性消失:PSDText.parse成功 → 可编辑文本层;解析失败 → 落入PSDText.rasterizedNote:"Editable Photoshop text becomes pixels and can't be retyped."

翻车条件全在 Compositor/IO/PSD/PSDText.swift 的源码注释里,任何一条命中就直接退回像素:

  • 垂直文字:Ornt == "Vrtc"直接返回 nil;
  • shear / 非均匀缩放:变换矩阵校验要求横纵比例差 ≤2%,否则退回栅格;
  • 多字体多字号混合排版:只保留第一个 style run,且报告 "Only the first text style was kept";
  • 文字变形 warp:非 none 的 warpStyle 追加 "The Photoshop text warp was omitted";
  • 假粗体/假斜体:FauxBold/FauxItalic 被丢弃并提示;
  • 两端对齐:降级为左对齐并提示;
  • 段落框无法表示:注释写明 "importing as point text would lose the wrap without saying so",宁可整层退回栅格也不静默降级;
  • 字体缺失:不是栅格化,而是用系统字体重绘并提示——这算温柔的一种。

最阴险的是最后一条兜底:即使TySh存在但渲染失败,图层像素依然来自 PSD 通道数据,画面完全正常。不点开图层、不尝试改字,你根本不知道它已经死了——这就是"直接翻车"的现场。

智能对象:链接内容永远进不来

kind()里命中SoLd/SoLE即判定为智能对象,PSDDocumentBuilder无条件追加:"The smart object was rasterized. Linked contents can't be edited."

智能对象在 PSD 里存的是复合后的栅格 + 一个指向外部内容的标记,Compositor 只读标记、不追链接。所以:图层位置、像素、透明度都正常,但你在 PS 里对智能对象做的所有非破坏性操作(替换内容、缩放滤镜、变换)在这里是一张死图。设计稿里那一堆"我塞进智能对象的源文件图层"不会跟着进来。

隐性翻车位:图层效果、位深与尺寸预算

还有几类不常被写进"踩坑贴"但同样致命的:

  • 图层效果整体丢弃:命中lfx2/lrFX/lmfx即kind == .effects,报告 "Layer effects were discarded, so the appearance may differ"。投影、描边、发光全没了,画面观感直接变化;
  • 非 8-bit / 非 RGB:PSDError.unsupportedDepth/ColorMode统一报 "Only 8-bit RGB Photoshop files can be imported"。拖一个 16 位或 CMYK 的 PSD,连报告都见不到,直接导入失败;
  • 超像素预算:DocumentLimits规定单边 ≤30000px、单 surface ≤2 亿像素、整文档预算随内存缩放。超预算时先尝试把所有图层裁剪到画布内(报告 "Cropped to the canvas so the file fits in memory"),还放不下就整文件拒绝。画布外的像素丢起来悄无声息。

绕坑三招:转换前检查清单

结合上面源码里的判定条件,拖 PSD 之前花 30 秒做这三件事,能把翻车率压到最低。

第一招:永远先读报告,再点 Import。这不是形式主义——报告里每一行都对应一段真实判定代码:栅格化、混合模式降级、效果丢弃、裁剪、跳过的调整层。看到 "becomes pixels"、"was rasterized"、"was discarded" 这类词,先想清楚这层你是否还需要编辑。不需要?直接进,反正有撤销;需要?Cancel 掉,回 PS 处理。

第二招:回 PS 里做"降级预处理"。对照源码里的判定条件逐项排查:

  • 文本层:改成水平单行、单一字体字号,删掉 warp 和假粗/假斜体,确认字体已装在 Mac 上(否则被系统字体替换);
  • 智能对象:接受它进来就是一张图——如果还要编辑,先在 PS 里"栅格化图层"或导出 PNG 再拖;
  • 图层效果:先在 PS 里"图层 > 图层样式 > 创建图层"或直接简化,把投影/描边烧进像素;
  • Dissolve 等缺失混合模式:改成 Normal 或先栅格化;
  • 16 位 / CMYK / Lab:在 PS 里转成 8 位 RGB 再存;
  • 大图:估算一下各图层像素总和,超过 2 亿像素级预算的文档会被裁剪到画布,画布外内容先自己裁掉。

第三招:把"翻车测试"变成回归测试。这个仓库本身就是这么做事的——CompositorTests/ 下有PSDRoundTripTests、PSDAdjustmentTests、PSBImportTests、PSDFixture一整组导入测试,EditorSession里甚至留了confirmConversions注入点,让测试可以跳过确认面板直接断言转换清单内容。如果你在自己的工作流里被某个 PSD 反复坑,最稳的解法是把它固化成测试夹具,把"这次导入产生了哪些转换记录"变成可断言的契约——这比任何经验清单都可靠。

最后给个总判断:Compositor 的 PSD 导入不是"毛坯房",而是分级交付——文件夹、蒙版、混合模式、调整层是精装;形状和简单文本是可编辑的软装;复杂文本、智能对象、图层效果是明确标注"此处为像素"的毛坯区。而它给这套分级交付配上了全文最值钱的那句话:Nothing is applied until you continue.翻车不可怕,可怕的是不知道要翻车——这套先报告后执行的机制,恰恰把"不知道"这件事从根上堵住了。

【免费下载链接】CompositorThe Photoshop alternative for Mac项目地址: https://gitcode.com/gh_mirrors/compos/Compositor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询