快速水印工作台与 PSD 互通
状态:P15-01 原尺寸图片工作流已实现;P15-02~06 待实施。更新于 2026-09-27。 对应 Roadmap P15。按下面的任务顺序逐项实施、验收,不把整份计划作为一次重构。
产品目标
在 Saier 内完成「拖入画作 → 套用个人水印 → 适当编辑 → 下载」,并能切换到完整绘画界面继续创作。快速模式与绘画模式共享同一个文档、图层、历史和导出管线,只改变工具展示,不创建第二套编辑器。
桌面优先,以熟悉的图层选择、拖动、变换、快捷键和撤销建立接近 Photoshop 的日常操作体验。首版围绕图片与水印编辑,不包含 Photoshop 的完整文字排版、调整图层、智能对象、滤镜和印刷色彩工作流。
实施前核对(P15 启动时)
| 能力 | 当前实现 | 本阶段需要补齐 |
|---|---|---|
| 导入图片 | Painter.loadImage() 创建可变换栅格层;拖放调用同一接口 | 当前会按已有画布缩小图片;需要「按原图尺寸新建」与「置入当前文档」两个明确动作 |
| 图片变换 | 拖动、缩放、旋转、翻转、数值编辑、锁比例、Shift 旋转吸附、确认/取消、撤销 | 直接选中水印、对齐吸附、复制、统一命令和焦点路由 |
| 快捷键 | B/E/S/D、笔径、缩放、撤销;底层有方向键 1/10 px 微调、Enter 和 Delete | site 与 runtime 两套监听需要协同,避免重复执行和多 Painter 串扰 |
| 图层与工程 | raster/group、变换、蒙版、剪贴、saier.project v2,可读取 v1 | 可编辑文字/图片来源、个人预设、可下载的本地工程入口 |
| 保存 | site 的保存命令目前写本地草稿;另有云端工程流程 | 区分保存草稿、下载可编辑工程和导出成品,不能把草稿成功等同于文件已下载 |
| PSD | 已依赖 ag-psd@31.0.2,有 readPsdDocument() 与基础单测 | 尚未接入 site 打开流程,没有产品级 PSD 导出与兼容性报告 |
源码入口:
packages/saier/src/painter.ts、packages/saier/src/layers/、packages/vue/components/PainterTransformBar.vue。site/app/constants/painterCommands.ts、site/app/composables/useSitePainterShortcuts.ts、packages/saier/src/keyboard/index.ts。packages/core/src/format/project.ts、packages/core/src/format/psd.ts、site/app/components/SitePainterApplication.vue。
现有 selection 主要服务可变换图片的控制框,不能据此宣称已经实现 Photoshop 式像素选区。现有 PSD reader 将分组展开为路径,映射少量混合模式;没有处理组级合成、蒙版、剪贴、文字编辑或效果渲染的完整语义,因此解析成功不代表外观保真。
首版交互
进入与导入
/保持主入口(遵循 D12),欢迎区域增加「给图片加水印」;进入后使用简化工具栏与水印属性面板。- 首次拖入/粘贴 PNG 或 JPEG:校正图片方向后,按实际图像像素新建文档,自动适配视口,原图层默认防误编辑。不得把「适配视口」变成缩小原始像素。
- 在已有文档中,区分「打开为新文档」和「置入为图层」;添加水印按钮进入图片置入或文字创建。失败的解码不留下空文档/半个图层。
- 导入为本地操作;云端同步沿用用户主动保存流程。超出支持的尺寸/像素预算时提供原因和显式缩小选项,不静默降采样。
- 快速模式切换到完整绘画模式时保留文档 ID、选中层和历史;房间 Activity 不使用这套导入入口。
水印与常用编辑
- 图片水印:透明 PNG、原始素材保留、缩放/旋转/翻转、透明度和层级。
- 文字水印:内容、字体、字号、颜色、描边、透明度;双击进入文字编辑。首版支持普通横排与手动换行,富文本、路径文字另行评估。
- 单击选择、拖动移动;角点默认保持比例,沿用当前 Shift 临时自由缩放规则;Shift 旋转吸附到 15°。
- 九宫格定位、边距、画布边缘/中心吸附;吸附阈值按屏幕像素计算,最终位置写入文档坐标。Alt 临时关闭吸附。
- 支持多个水印、复制、删除、显隐和透明度调整;首版单对象操作,多选联合变换后置。
- 原图的防误编辑是独立的编辑锁定语义,不能用当前
lockAlpha代替。快速模式还须防止画笔/删除快捷键绕过这一约束。
快捷键与操作事务
| 操作 | 计划行为 |
|---|---|
V | 选择/移动图片或水印;选中时直接显示变换框,保留现有 S 别名 |
T | 添加/编辑文字水印 |
Space + 拖动 | 临时平移视图,松开恢复之前的工具 |
方向键 / Shift + 方向键 | 文档坐标微调 1 / 10 px |
Enter / Esc | 提交/取消当前变换;文字编辑时按编辑器语义处理 |
Delete / Backspace | 删除选中可编辑水印;输入框聚焦时正常编辑文字 |
Ctrl/Cmd+Z、Ctrl/Cmd+Shift+Z | 撤销/重做,按钮与键盘调用相同命令 |
| 复制、导出、适配视图 | 提供可见按钮和菜单,快捷键经浏览器冲突验证后再启用 |
Web 不把 Ctrl/Cmd+T 作为必需的变换入口,它与浏览器新建标签页冲突;桌面 adapter 可以提供平台快捷键。保留现有 H 重置视图等绑定,避免无提示重映射。
命令优先级固定为「模态框/文本输入与 IME → 活动文档 → 画布工具」。失焦、切换文档、关闭面板时释放 Space/修饰键状态。输入框、contenteditable 和中文输入法组合输入期间不触发画布快捷键。
一次拖动、一次滑块拖动、一次文字编辑提交或一段连续方向键微调只产生一条历史记录;Esc 回到事务开始状态。点击下载/保存前先提交有效编辑,取消导出不修改画作。
架构与数据边界
遵循 D2、D7、D12、D15:文档像素不受缩放/DPR 影响;Vue 只展示状态;像素快照继续保证工程打开结果。
| 层 | 职责 |
|---|---|
@saier/core | 文档图层、编辑锁定、可编辑来源描述、历史命令、格式校验/迁移、PSD 数据适配 |
saier / @saier/pixi | 图片解码与文字栅格化接线、图层呈现、命中检测、变换框、吸附参考线 |
@saier/vue | 可复用变换与属性控件,调用 controller/runtime 命令 |
site | 快速模式、水印预设、打开/导出流程、文件 adapter 与兼容性提示 |
可编辑来源与像素快照
不立即把现有 raster engine 改写成完整矢量排版引擎。计划为栅格层关联可编辑来源:图片引用内嵌原始素材,文字保存内容、字体标识、字号、填充和描边等属性。变换、显隐、透明度、顺序只保留在现有图层模型,避免两份真相。
- 来源信息用于再次编辑/重新生成图层;已保存的像素快照用于可靠打开和预览。打开工程不能自动重排文字而改变外观。
- 文字栅格化通过注入的 renderer 完成,DOM/字体加载放在浏览器适配层,core 不依赖 Vue 或 Pixi。
- 每次文字属性更新原子提交来源与派生像素;异步字体加载或栅格化使用文档/图层修订号,丢弃已经过期的结果。撤销同时恢复来源、像素和变换。
- 字体缺失时保留快照,并在再次编辑前展示替代字体选择;首版不自动打包系统字体,不承诺跨机器重新排版逐像素一致。
- 对来源管理的水印层直接绘画前,提供可撤销的「转为普通像素层」动作,避免下一次修改文字覆盖已经画出的内容。
- 个人预设保存素材、样式、锚点、相对边距和相对尺寸,实例化后属于独立图层;修改预设不追溯修改旧作品。PNG 等二进制素材放 IndexedDB,避免大量 base64 塞入 localStorage。
个人素材库与云同步
2026-09-28 实施进度:主界面的水印插件已支持自定义 PNG / JPEG / WebP,以及显式上传、 搜索和选入 Drive 私有素材。saier-assets-api 通过当前登录 UID 委托 Drive,沿用 @yunlefun/assets 契约和统一 user-storage-api 配额。生产后端已完成合成 PNG 的上传、 验收、下载哈希、去重与拒绝未授权访问验证,Drive 网页可见同一条素材。前端发布开关 NUXT_PUBLIC_SAIER_PRIVATE_ASSETS_ENABLED 默认关闭,需要在发布此工作台时显式开启。 当前连接绑定已授权用户的实际个人空间;其他用户需要自己的空间连接,不能复用同一个 consumer credential 自动开通。详细部署与验证见 cloudbase/functions/saier-assets-api/README.md。
2026-09-27 需求补充:已有水印素材需要上传并跨设备同步,纳入 P15-03a。未登录仍可本地使用;登录后提供「同步到我的素材库」,云端素材默认仅本人可见。
- 复用现有账号、
user-storage-api上传预约/完成、下载、共享配额与失败清理流程;新增明确的水印素材和预设数据契约,不伪装成工程文件或笔刷库。 cloudFileKind.ts的project/brush-library与笔刷库单文件替换流程继续保持独立;素材通过 Drive 的asset委托进入统一存储,使用私有素材桶、owner 过滤和配额验收,不伪装成笔刷库文件。- PNG 水印保留原始透明素材;二进制文件按内容哈希去重。素材记录包含名称、尺寸、格式、缩略图、内容哈希和版本;预设引用素材并保存布局/样式规则。
- 同步状态区分「仅本机、待同步、已同步、失败」;未完成云端确认不能标记已同步。离线编辑先保留本地,重连可重试;切换账号时隔离缓存与待上传队列。
- 以版本号检查并发修改,避免两台设备静默覆盖;删除使用可同步的删除记录,并检查预设引用。删除素材库中的素材不破坏已保存工程中的内嵌副本。
- 素材同步与画作上传是独立动作。选择同步个人水印,不意味着同时上传当前画作,也不自动授权把作品发给 AI 服务。
智能水印布局与保护区域
2026-09-27 需求补充:支持「避开脸部等主要部位」的规则,纳入 P15-04a。这里的脸部包括绘画角色、二次元、兽设和风格化人物,采用多模态语义分析作为主要识别路径,不假定普通真人脸检测器能够覆盖。AI 识别保护区域、解释规则并提出位置;Saier 使用原始水印图层进行确定性合成,继续保留图层编辑和撤销能力。水印处理明确不调用生图/改图模型,不用生成结果替换原画或水印素材。
- 自然语言与可见规则控件对应,例如「使用我的白色签名,优先右下角,避开脸部,透明度 25%」。规则落到受校验的结构化参数;AI 输出不能直接成为任意可执行命令。
- 保护区域统一用文档坐标的矩形/蒙版表示,记录来源(模型建议/用户标注)、修订号和不确定性说明。区域可以是角色脸、眼睛、标题、已有签名、重要道具等。角色脸区域加保护边距,用户可显示、增补、删除和调整区域;模型自报的置信分数不视为经过校准的准确率。
- 「避开脸部/手动保护区域」作为硬约束,主体重叠、背景繁杂度、可读性和位置偏好作为可配置优先级。检测不到脸不能被解释为确定没有脸。
- 布局器生成多个候选位置,使用水印变换后的实际覆盖范围检查保护区域与画布边界。没有满足硬约束的位置时保留当前布局并提示调整尺寸/规则,不能静默降低保护要求。
- 首先提供手动保护区域和确定性的候选布局,再接多模态语义分析。MediaPipe 一类真人脸检测器仅作为以后可选的照片辅助能力,不作为绘画角色脸识别的默认方案或前置依赖。
- 分析通道由统一 provider 契约隔离:云乐坊 AI Runtime 与本机 Codex 返回相同结构的结果。选择启用时明确实际模型服务商与图像发送目的地;默认不自动发送整份工程或原尺寸作品。产品云端入口沿用云乐坊账号、统一 AI Runtime 与 AI 点账本,浏览器不直连模型绕过计费,也不放置平台凭证。CloudBase 只是 Runtime 可选择的下游模型通道之一。
- 现有
pictionary-ai-remix.cjs是 Activity 图片生成能力,不能直接作为主体定位 API;新建工作台分析接口,复用鉴权与用量管理思路,保持与房间 Activity 的数据隔离。 - 缓存按图像内容、分析尺寸、模型/规则版本区分。异步结果带文档 ID 与修订号;切换文档或画作变化后丢弃旧建议,缩略图分析坐标需正确映射回文档像素。
- 展示候选布局和保护区域,用户应用后产生一次可撤销的图层操作。分析失败仍可手动放置水印;不承诺自动检测永远正确。
技术调研入口:Gemini 图像理解 提供对象检测/分割接口说明;OpenAI 视觉限制 明确提示定位和识别可能出错。多模态模型的语义理解并不自动保证像素级定位准确,需用真实画作评测、展示保护区并允许校正,不能仅凭模型名称承诺效果。
分析请求与确定性合成契约
- Saier 生成方向已校正的画作分析快照,记录
documentId、修订号、内容哈希、分析图尺寸和坐标映射;请求只携带这张快照与规则。图片内文字作为画作内容,不作为执行指令。 - 分析端返回受 JSON Schema 约束的保护区域:语义标签、相对分析图的归一化边界框、保护优先级、不确定性说明,以及可选的位置建议。首版使用带边距的矩形;多边形/精细蒙版须经过独立定位验证后再开放。
- Saier 校验版本、有限数值、边界范围、区域数量、文档修订号和坐标映射。Schema 合法只代表结构正确,不代表区域识别正确;不接受可执行脚本、任意文件路径或新的生成图像作为分析结果。
- 布局器根据保护区域、现有水印尺寸/透明轮廓和用户规则计算候选位置,检查旋转后覆盖范围与重叠。云端与 Codex provider 共用这一布局器,测试采用固定区域输入以保证相同输入得到相同结果。
- 预览显示保护区域和候选位置;应用只更改水印图层的变换/透明度等属性。原画像素保持不变,PNG/JPEG 仍由现有确定性合成管线导出,应用可撤销。
可选的本机 Codex 分析通道
- 本机已核对
codex-cli 0.154.0:codex exec支持图片输入、--output-schema和--output-last-message;可作为短任务原型。正式交互可使用 Codex App Server 的localImage、outputSchema、进度事件与取消接口。协议能力按实际安装版本检测,不要求用户升级到未经验证的版本。 - Electron 优先通过主进程的受限 IPC 调用本地分析适配器;纯 Web 可选用户主动连接的本地 companion。网页不能直接启动本机 CLI,也不直接暴露通用命令执行接口。
- companion 只监听本机,通过明确配对、来源校验和会话凭证接收限定格式的分析请求;传入图片字节/请求 ID,不让网页指定任意磁盘路径、命令或工作目录。
- 每个分析任务使用隔离的临时输入与最小读取范围;不加载无关仓库上下文,不授予原画/工程写入权限,禁用无关工具、插件与生图能力。只读沙箱不等同于禁止全部工具,实施时须单独验证工具限制和实际权限。任务结束清理输入和结果临时文件。
- 本机运行 Codex 不等于离线推理。若当前 provider 使用云端模型,图像仍发送到对应模型服务并受该账号/provider 的用量限制;完全离线的视觉模型是另一条需独立评测的 provider,不作为本地 Codex 接入的默认承诺。
- 首版接入本机 Codex 运行时。在已打开的 Codex 桌面聊天中自动显示任务、继续对话并回填结果,是独立的桌面 UI 集成,当前未验证;不把本对话可用的线程工具当作 Saier 网站普遍可调用的接口。
- 验收覆盖 Codex 未安装/未登录、模型不支持图片、输出不合法、取消/超时/限额、旧结果回流、恶意图片文字和本地桥接来源隔离;故障时保留手动编辑能力。
官方依据:Codex 非交互结构化输出、App Server 图片输入和结构化结果。当前实现与实测范围见下方 P15-04a 接入原型记录;正式 App Server 长连接仍待实现。
CloudBase 多模态能力核对(2026-09-27)
对 yunlefun-8g7ybcxc7345c490 实际调用 DescribeAIModels 与 DescribeManagedAIModelList:
- 已启用的
cloudbase组包含glm-5v-turbo,目录明确标注多模态理解;建议作为首个云端对照模型。 - 托管目录还包含
qwen3.5-flash、qwen3.5-plus、kimi-k2.6、hy-vision-2.0-instruct等多模态模型。目录可用不等于环境已启用,不能直接把所有目录模型放进可调用列表。 - 官方多模态文档 支持在消息内容中组合文本与
image_url,图片可用 Base64 data URL。只请求保护区坐标,不请求生成图片。 DescribeEnvPostpayPackage未返回有效的pkg_tcb_tokencredits_*包。这个查询只检查 CloudBase 平台资源包,不能推断云乐坊用户没有 AI 点,也不构成用户使用云乐坊托管 AI 的统一前置条件。此前将此结果扩大为整个云端接入的阻塞项,现已纠正;下游模型采购/额度由 Runtime 的具体 provider 单独检查。- 网页未来只呈现 Runtime 注册、允许当前账号使用且经过图片输入验证的模型别名;同一快照/规则可分别交给 Codex 与云乐坊 AI,比较保护区域、耗时与布局结果。云端选项已接统一 Runtime HTTP 协议,源码已注册 Saier 并增加图片输入;生产策略启用和部署后的真实扣费联调仍待完成。
云乐坊账号与 AI 点复用(2026-09-27 源码核对)
YunLeFun/www.yunle.fun/cloudfunctions/account-api/ai-points.js是现有 AI 点账本;已有账户读取、逐任务预留、按确认用量结算、失败释放和幂等保护。app/composables/useAiPoints.ts调用getMyAiPointAccount/listMyAiPointTransactions,不需要 Saier 再建余额表。YunLeFun/api/packages/ai-runtime/src/billing.ts的PolicyBillingLedger已实现ai_points_metered。Saier 云端分析应注册独立能力(例如saier/watermark.analyze),复用它的鉴权、预留、用量、重试和结算;图片合成、改色和下载留在本机,不额外产生模型计费。- 云乐坊用户 AI 点与 CloudBase Token Credits 是不同层次的余额。前者属于用户产品账户;后者属于某个下游服务商资源账户,不能把两者混为一个余额或要求每个用户购买 CloudBase 资源包。
- 当前源码已注册
saier/watermark.analyze,消息支持一段文字加一张受限 PNG。同步路径复用统一鉴权、幂等、用量与 AI 点账本,操作表只记录请求哈希和状态,禁止通过异步任务接口持久化图片。生产部署和真实账本联调不包含在本地验证结果中。 - 本次核对的是已有源码与交付记录,没有读取用户私有余额、发起兑换、扣点或变更线上配置。
PSD 素材预设与提示词分工
- 素材包/结构化预设是事实来源:原始 RGBA、水印角色、混合模式、图层透明度、相对尺度、配色范围、保护边距和版本;原 PSD 布局只作参考,新图必须重新定位。
- 版本化提示词负责语义分析:识别绘画角色脸与重要区域,提出有限的资产角色、位置、颜色和透明度;输出 JSON,不生成或改写画作/署名像素。
- 确定性工具负责执行与验收:颜色调整保留原始 alpha,应用时再乘图层透明度;保护区碰撞校验、组合图层、导出、快照修订检查不交给模型自由发挥。
- Skill 是可选的调用外壳:重复批处理工作流稳定后再封装“选择预设 → 分析 → 预览 → 合成 → 验证”。不把私有素材放进公开 Skill,不用提示词替代数值预设或代码验证。
- 本次参考 PSD 包含三段缎带、全画面边框/署名、两处签名,以及叠加/线性光纹理。噪声图层已有针对旧画角色脸的透明洞,不能当作通用保护区域。原始签名图层含外发光/描边参数,提取 PNG 保留栅格像素,效果参数单独保存,不能声称 Photoshop 外观完整复现。
- 个人素材输出在本机 Downloads,没有加入
site/public或上传云端。实验页现支持单张 PNG 及saier.watermark-presetv1 内嵌 PNG 预设包;提供多素材布局、颜色/透明度与位置调整,仍未接入预设云同步。
格式策略
无需另造一种工程体系,也不强制用户保存工程。 一次性任务可以直接图片进、图片出;需要继续编辑时沿用现有 Saier 工程。
| 格式 | 角色 | 保留内容 |
|---|---|---|
| PNG / JPEG | 成品导出 | 合成画面;PNG 可保留透明,JPEG 明确选择底色和质量 |
.saier.project.json | 原生可编辑工程 | 图层、像素、变换,以及计划新增的水印来源与内嵌素材 |
| PSD | 与 Photoshop 等软件交换 | 分级支持的图层与图像,具体能力见下节 |
现有格式是 saier.project v2(兼容 v1),不是已实现的 ZIP .saier 容器。计划在增加结构化来源、素材与编辑锁定时升级到 v3,并保留 v1/v2 导入测试;不把嵌套对象偷塞进只支持标量的 metadata。
第一版继续 JSON 容器,素材按 ID 去重内嵌,保证移动文件后仍能打开;只有实测文件大小/解析内存成为瓶颈时再设计 ZIP 容器。实验入口先行提供独立 saier.watermark-preset v1 交换格式,本地预设不依赖云端;它不代替主画板工程 v3。
v3 交付必须同时审计草稿、工程下载、云端校验和 room snapshot 消费者。未支持 v3 的消费者显式拒绝或禁用对应动作;不能丢弃来源后仍宣称完整保存成功。当前不扩展 Activity 或多人房间的实时水印编辑协议。
PSD 兼容等级
继续评估和复用已经安装的 ag-psd,先限定 RGB、8 bit/channel、普通 PSD。支持范围按 fixture 与目标应用实测扩展,不能由依赖库的 API 名称推导出产品兼容承诺。
A:读取合成预览,给 PSD 作品加水印
- 读取 PSD 保存时携带的合成图,作为一张原图进入水印流程;UI 明示「作为合成图片打开」,不显示为完整分层导入。
- 合成图不存在或无法解码时明确失败,并提示从 Photoshop 导出 PNG 或使用后续受限分层导入;不把部分图层拼接伪装成原图。
- 使用库提供的合成图不代表实现了图层效果、ICC 转换或 Photoshop 合成器。初期仅对已验证的 RGB/sRGB 样例宣称外观一致,其他配置展示限制或拒绝。
B:基础分层导入
- 保留位图层、顺序、名称、位置、显隐、透明度,以及经过验证的分组和混合模式。
- 为组级显隐/透明度、pass-through、蒙版、剪贴、文字、智能对象、调整层和图层效果建立逐项检测。
- 不支持的内容在打开前给出兼容性报告,允许改用合成图。只有测试确认的内容才进入分层编辑;现有「不支持混合模式转 normal」行为不能无提示进入正式 UI。
- 文字、形状或智能对象只能在确有可用位图且效果可解释时作为栅格层导入;不承诺文字可编辑或智能对象可还原。复杂组级效果不能简单对子层乘透明度来替代。
C:基础分层 PSD 导出
- 首版优先导出「原图 + 独立水印」这些普通栅格层,并写入正确的合成预览。
- 变换烘焙到各层导出像素和偏移,文字水印按独立像素层输出;它们在 Photoshop 中仍可独立移动/调整透明度,文字内容编辑留在原生工程。
- 图层透明度/混合模式只应用一次,正确处理预乘/直通 alpha;旋转层的边界、裁切和透明边缘必须有像素回归。
- 对当前编辑器里的复杂蒙版/剪贴/不支持合成模式,提前列出影响;提供明确的合并导出选择,不静默改变外观。
- 不覆盖来源 PSD;导出新文件。保留未解释的 PSD 数据块并不能保证往返保真。
CMYK、16/32 bit、PSB、可编辑 PSD 文字、智能对象往返和高级效果不属于本轮。原生格式与 PSD 是互补关系:前者保存 Saier 编辑语义,后者交付明确的交换子集。
解析与验证要求
- 在解码像素前检查文件头、文档/图层边界、图层数与累计像素内存预算;用安装版本已提供的
useRawData/totalMemoryLimit验证受限解析路径。 - 限制针对所有图层的累计资源,不能只检查文档宽高或压缩文件大小;错误不能破坏当前已打开文档。
- PSD 解码按需加载并放到可取消的 Worker;这不等于把绘画热路径搬进 Worker。
- 同一库写入再读取只是基础检查。增加合法来源的 Photoshop 保存样例,验证图层属性和合成结果;导出文件需在真实 Photoshop 中打开验收。没有目标软件验证时只能标记为「基础互通测试通过」,不能标记「Photoshop 兼容已验证」。
外部依据(核对于 2026-09-27):Adobe PSD 文件规范;ag-psd 官方说明。库负责文件读写,修改内容后的文字位图和合成图仍需应用生成;其文字与部分颜色模式支持有限。
实施顺序与验收
P15-01 已完成下述验收,P15-02~06 待实施;只推进当前任务,完成对应验收后再进入下一项。
后续实施的默认决策
继续实施不需要重新选择仓库或渲染引擎;沿用当前 Saier 文档、图层、历史和平台 adapter。以下默认值用于限定交付范围,可以在对应功能实施前根据产品偏好调整:
- 水印首先服务个人署名/Logo,提供图片与可编辑文字、九宫格定位、相对边距和透明度。满屏重复/斜向铺排需要单独的重复布局与导出验收,不视为当前单对象布局已经覆盖。
- 先完成 P15-02~04 的图片/文字水印闭环,再接 PSD。PSD 默认优先「读取合成图 → 加水印 → 导出图片」;分层 PSD 导出与已有 PSD 图层编辑分别验收。
- 工程延续 JSON 容器,v3 保存来源与内嵌素材,读取兼容 v1/v2。素材依赖不能丢失;旧格式与房间消费者的兼容策略在 P15-02 中显式实现、测试。
- 个人预设保存在本机 IndexedDB,不要求登录;根据补充需求,P15-03a 增加登录后的个人素材/预设云同步,沿用现有共享配额。云同步与当前画作的保存是独立操作。
- P15-04a 增加智能布局:手动保护区与规则布局先行,再接多模态画作语义分析,支持云端接口/可选本机 Codex 运行时。角色脸识别不依赖 MediaPipe;水印始终由 Saier 确定性合成,不接生图能力。
- 文字先支持普通横排和换行,沿用可用字体;字体缺失保留像素快照,重新编辑时再选择替代字体。自动嵌入字体和完整 Photoshop 字体排版不属于首版。
- 本地实现和验证不包含生产部署、云资源变更或 Git 提交/推送。真实 Photoshop 验收保留独立状态,未完成时不宣称已验证 Photoshop 兼容。
P15-02 消费者审计入口
| 消费者 | 实施时必须覆盖的边界 |
|---|---|
packages/core/src/format/project.ts | 当前只读 v1/v2;新增 v3 版本、来源/素材引用与尺寸校验,保留旧工程测试 |
packages/saier/src/painter.ts | 导入后的透明边界、图层变换与来源尺寸一致;来源/像素更新和撤销成对;失败不留下半个文档 |
site/app/utils/projectDraft.ts | 当前草稿外壳对工程版本校验较弱;恢复前验证支持范围,保留完整来源 |
site/app/composables/useYunlefunCloudFiles.ts | JSON 文件上传/下载保留 v3 信息;服务端校验能力未验证前不得假定兼容 |
site/app/composables/useYunlefunCloudRooms.ts 与房间 snapshot | 现有实时操作协议不含来源编辑;不能仅升级文件版本就开放多人水印编辑 |
| site 本地工程下载 | 与本地草稿、成品图片导出区分;下载并重新打开后来源和图层可继续编辑 |
| 任务 | 主要改动 | 退出条件 |
|---|---|---|
| P15-01 原尺寸图片工作流 | 统一打开/置入入口、拖放/粘贴、原图尺寸文档、导出选项 | PNG/JPEG 打开再导出尺寸正确;EXIF 方向正确;缩放/DPR 不改导出尺寸;取消/失败不损坏当前工程 |
| P15-02 编辑对象与工程契约 | 图层关联来源、编辑锁定、v3 迁移、来源与像素事务、本地工程下载 | 旧 v1/v2 可打开;新工程重新打开仍能编辑来源;撤销一致;草稿/云端/room 版本边界明确 |
| P15-03 图片水印与预设 | 快速模式、图片水印属性、九宫格定位、IndexedDB 预设、多个实例 | 换横图/竖图后预设按比例适配;刷新可恢复;删除/变换可撤销;原图不会被误编辑 |
| P15-03a 素材与预设云同步 | 私有素材库、二进制去重、版本冲突、账号隔离、云存储类型与规则 | 跨设备可恢复;离线/重试无重复素材;失败不显示已同步;并发修改无静默覆盖;删除不破坏旧工程 |
| P15-04 文字与快捷操作 | 文字生成与重新编辑、吸附、复制、统一命令焦点与历史合并 | 中文输入不误触;字体缺失不改变已有快照;变换与属性一次操作一次撤销;两个 Painter 不串扰 |
| P15-04a 智能水印布局 | 角色/主体语义保护区域、多模态 provider、可选本机 Codex、规则布局 | 角色画作样例单独评测;区域可校正;布局满足保护区约束;旧结果不串文档;原画像素不变且不调用生图 |
| P15-05 PSD 合成图入口 | 按需解析、资源预算、取消、合成图导入和能力报告 | 支持样例得到正确尺寸/像素;缺合成图、非支持模式、超限/损坏输入有明确失败;主界面保持响应 |
| P15-06 PSD 基础分层互通 | 基础分层导入/导出、兼容报告、目标软件 fixture | 正常层级/透明度/偏移正确;复杂效果显式降级;Photoshop 实机验收状态如实记录 |
第一个可用里程碑为 P15-01~04:图片/文字水印完整闭环;P15-03a 与 P15-04a 分别增加云同步和智能布局,独立验收。PSD 不阻塞这个里程碑,P15-05~06 交付文件互通。
首轮实际编码从 P15-01 开始:先复用 importImagePixels 和现有 document API,把「按原图新建」与「置入当前文档」分开,再接拖放与粘贴。不要继续对所有导入统一调用会按旧画布尺寸降采样的 loadImage()。
P15-01 交付记录
Painter.openImage()在解码成功后按图像尺寸建立新文档、适配视口;loadImage()保持适配当前画布的图层置入语义。原文档继续保留。- site 文件菜单与工具栏区分「打开图片」和「置入图片为图层」;拖放/粘贴提供两种动作选择,输入框粘贴不触发导入。文件入口沿用 platform adapter,图片解码可取消,切换文档取消旧请求。
- 导出面板支持 PNG 透明/指定底色、JPEG 底色/质量和文件名;像素按文档尺寸输出,不受视口缩放或显示 DPR 影响。导出前提交当前变换。
- site 图片入口限定 PNG/JPEG;初始预算为单边 8192 px、总计 1600 万像素,超过预算需要用户明确选择缩小。尺寸检查发生在浏览器图像解码之后、像素 canvas 分配之前,不等同于对解码器内存的硬限制。
- Activity、云端房间与笔迹回放期间不接受这套图片导入,避免修改未支持图片同步的文档。
- 浏览器回归覆盖原尺寸/alpha/DPR、JPEG EXIF 方向、解码失败/取消/超限、图层置入与撤销、PNG/JPEG 下载;页面回归覆盖拖放/粘贴/Esc、输入焦点与窄屏导出面板。绘画主页与
/shodo渲染正常。 - 本任务未升级 v2 工程格式;原始素材保留、图片编辑锁定、预设、文字水印和 PSD 仍按后续任务交付。简化水印模式中的首次拖入直接打开,在 P15-03 接入。
浏览器验收使用本机 Chromium 自动化与 1440×1000/390×844 视口;Safari、真实移动设备、大图性能上限与 Photoshop 互通尚未验收。
2026-09-27:P15-04a 接入原型
根据新增的 Codex 运行时接入要求,先验证外部分析链路,保留 P15-02~04 的正式编辑器工作顺序,不把本原型视为这些任务已完成。
/watermark-lab是站内实验入口:PNG/JPEG 画作和水印上传、Codex/纯本地合成切换、保护框预览与移除、水印宽度/透明度、确定性候选位置和 PNG 下载。不会替换主画板的文档状态。scripts/watermark-bridge.mjs使用 Node.js 24+ 和本机已登录的 Codex CLI(验证版本 0.154.0)。只监听127.0.0.1,校验 Host、精确 Origin 和每次运行随机生成的配对码;同一时刻一个任务,默认 120 秒超时。关闭网页请求或桥接进程会取消分析。- 原型通过
codex exec --json --image --output-schema执行,不读取用户 config、仓库指令或宿主技能;关闭生图、shell、浏览器、插件等无关能力,使用只读沙箱,拒绝意外工具事件。网页传图片字节,不能指定本地路径、可执行程序或工作目录。图片临时文件在结束后清理。 - 浏览器发送最长边 1024px 的 PNG 快照,并绑定文档 ID、修订号、SHA-256 与尺寸。服务端核对图片头与哈希;双端校验返回坐标,切换规则/图片或取消时丢弃旧结果。识别框和保护边距映射回原图尺寸后再合成,导出不含保护框。
- 真实 Codex 调用已返回结构化区域;桌面应用可读取该运行时新建的任务记录,网页提供官方
codex://threads/<id>打开链接。macOS 可在完成后通过官方深链接自动打开这条独立任务,页面可关闭此选项;已验证本机能够分派深链接。尚未实现向选定的已有桌面聊天追加任务、执行中展示或从该聊天订阅回填。本机没有可连接的 app-server daemon 控制 socket;不修改桌面私有数据库,也不把本对话的内部线程工具作为网站 API。 - 当前任务的临时图片会清理,桌面记录中的旧图片路径不保证可再次打开;继续聊天和素材留存策略需在正式桌面集成时解决。
- 单张水印仍使用确定性候选位置;整套预设由 AI 给出多个位置、角度、配色和透明度,客户端核验并合成。无布局时禁止下载,保护区及短边 2% 边距从覆盖层中清除。区域暂只可移除,拖动/重画保护区、精细蒙版、图层撤销、预设云同步及角色脸准确率评测尚未完成。
本地试用:
pnpm dev
# 另一个终端,精确匹配浏览器地址的 Origin
SAIER_ANALYSIS_ORIGIN=http://localhost:8080 node scripts/watermark-bridge.mjs打开 http://localhost:8080/watermark-lab,将桥接终端的一次性配对码填入页面,再上传图片并点击识别。配对码只留在当前页面内存,不写入 localStorage。纯本地合成不需要启动桥接或调用模型。公开 HTTPS 网站访问本机服务还需要验证浏览器的本地网络权限,不作为本次已验收范围。
整套预设与统一 Runtime(服务与前端均已发布)
- 预设包含名称、规则、最多 12 个素材,PNG 字节内嵌;单包最多 64 MiB、总像素 3200 万。读取前验证 PNG 头尺寸,不请求预设中的任何外部 URL。
node scripts/watermark/pack-preset.mjs /path/to/extracted-assets将watermark-recipe.json和 PNG 打包成.saier-watermarks.json,同时输出分析提示词。优先使用reusableAssets:缎带、独立标题/署名/边框、主图标,以及从无空洞部分裁出的纹样和细纹理循环单元。原始纹理含旧脸部空洞,不能整张迁移。- 选择画作、导入整包,启用需要的素材,选择 Codex 或云乐坊,点击“分析并套用整套预设”。支持逐实例改位置、宽度、角度、颜色、透明度或移除,修改无需重新调用 AI;更换画作、规则或素材集合会丢弃旧布局。
preset-contract.ts/protocol.ts是双端协议,scripts/watermark/sync-runtime-contract.mjs同步到 YunLeFun/api。布局坐标归一化,素材高度由原比例推导;双端拒绝未知素材、无效数字、颜色与旋转越界。- 云端发送最多 1 MiB / 最长边 1024px 的 PNG,过大时进一步缩小分析图;原尺寸画作和水印 PNG 仍用于本地导出。服务端验证哈希、CRC、尺寸和解压长度;不使用生图。
- 网页复用云乐坊会话调用
POST /ai/v2/apps/saier/watermark;Runtime 采用同步账本链路,不保存分析图片。服务端模型须同时已启用并标记为支持多模态,客户端不能提交模型或价格。 - 云端策略键为
application:saier,没有启用策略时在预占前拒绝。部署说明及默认关闭的配置样例在 YunLeFun/api 的docs/saier-watermark-runtime.md/docs/saier-watermark-policy.example.json。2026-09-28 已发布ai-runtime-028并启用计费,真实固定测试账号的账本验收通过;前端于同日随 Saier1e18a3d发布。云端停止等待不能保证取消已发出的模型请求。 /watermark-lab的画作预算为单边 8192 px、3200 万像素、25 MiB,支持本次 4800 × 4300 原图;主绘画页的 1600 万像素限制保持原状。云端分析仍只发送缩略图,下载按原图尺寸合成。
测试与交付
- 纯逻辑:预设相对布局、吸附计算、版本迁移、来源/素材引用校验、PSD 能力报告和预算检查。
- 浏览器:原尺寸导入导出、变换/撤销、透明 PNG 边缘、文字异步更新、输入法与失焦、字体缺失、IndexedDB 恢复和多文档切换。
- 像素:PNG 原图在未编辑路径的尺寸/alpha,水印合成与屏幕预览一致,PSD 独立图层合成与导出 composite 一致。JPEG 使用容差,不要求有损格式逐像素一致。
- 回归:原绘画入口、
examples/vue、examples/react、/shodo、Activity 文档隔离;移动端所有新增操作都有按钮入口。 - 变更对应的测试通过后,运行
pnpm lint、pnpm typecheck、相关库/site 构建;格式或公共 API 变更覆盖消费者与示例构建。文档改动运行pnpm docs:build。 - 性能记录固定桌面机器与真实移动设备上的导入/预览/导出耗时、峰值内存和取消响应;以 4096×4096 原图与多个水印为代表样例。上限由实测决定,不把“可打开”描述成“流畅”。
实施准备核对
- [x] 明确在 Saier 内实施,统一文档与导出能力。
- [x] 核对已有变换、快捷键、原生格式与 PSD reader。
- [x] 明确首轮任务、数据边界、格式策略和验收条件。
- [x] 完成 P15-01;后续任务依次推进。
- [ ] 使用真实 Photoshop 完成互通验收。
前一轮整包验收:11 项 Saier 单元/浏览器像素测试、3 项页面流程、41 项 Runtime/HTTP/计费相关测试通过;lint、类型检查、站点/Runtime artifact/文档构建通过。一次真实 Codex 调用在参考画面返回 26 个保护区域、3 个素材落点以及识别不确定性警告,双端协议校验通过;这不是角色检测准确率评测。
2026-09-28 生产验收:云端 glm-5.3-flash 对新画作返回 7 个保护区域、4 处素材布局。固定测试账号预占 91.5 AI 点,实际扣除 9.92 点,释放 81.58 点,剩余预占为 0;失败调用全额释放,重复幂等键不重扣。真实云端结果在本地浏览器回填后导出 4800 × 4300 PNG,保护区域及边距像素校验通过。布局主要位于画面边缘,是轻量展示样例,不代表防裁剪覆盖或模型识别准确率。公开网站 SSO 到下载的完整交互尚未验收。
PSD 效果校正(2026-09-28)
维护者确认需要主体十字覆盖,上一版边缘布局不符合要求。新规则把横缎带与长纵缎带相交于主体,心形主图标和 FOR DISPLAY ONLY 放在主体轮廓内,满屏小字与细纹理覆盖全画布,仅新识别的脸部等区域留空。
- 直接检查参考 PSD:三段缎带均为正常混合、图层不透明度 100%,无
effects、蒙版或非默认 Blend If;半透明来自原始 PNG alpha。参考中的模糊已烘焙在「背景 拷贝」,不是缎带上的图层样式。 - 预设新增
backdropBlur(画布短边比例,限制 0–0.03)。客户端先从未修改的原图生成局部模糊底,再画所有缎带,避免交叉处后画的模糊抹掉前一条缎带。参考未保留模糊参数,0.013 是外观复刻值,不承诺像素级复原 Photoshop 操作。 blendMode支持 normal、overlay、linear-light。细纹理使用叠加 105/255,小字纹样使用线性光 100%;线性光通过分行像素合成实现,因为 Canvas 没有同名原生模式。混合模式语义参考 Adobe 文档。repeated-watermark/micro-texture的 width 为循环单元宽度,原点固定、覆盖全画布;frame单独保留四角并延展边线。标题、署名从边框拆出,避免横幅画作拉伸文字。- 所有效果合成后恢复保护区及短边 2% 边距内的原始 RGBA,包括透明像素。成品仍是 4800 × 4300,原图文件不变。此次复用云端已有识别并人工补两个小玩偶脸,按参考修正布局,没有再次收费调用模型;不能把修正版称为新模型自动布局验收。
主色与脸部锚点构图(v3,v4 已调整配色与爱心尺寸)
维护者补充:边框和底部署名应使用画面主色系深色;爱心位于主脸左下方;十字向上调整并避脸。这些偏好抽象为 SUBJECT_CROSS_RULES,预设打包、Codex 分析与云端分析复用同一份规则;默认规则相同时,提示词不重复附带整段预设规则。
- 从主体服装和道具的大面积颜色取主色,排除白背景、肤色、孤立点缀。边框与底部署名统一使用该色系深色,保留 alpha;两类素材在预设中允许换色。爱心、纹理和缎带不随边框一起压暗。
- 爱心用主脸相对位置定位:中心偏左、下巴下方,优先肩部或上胸衣服;宽度从脸宽的 0.65–0.9 倍开始。拥挤时先缩小、微移,不固定到某个画布百分比。
- 横带优先上腰/躯干下半部,纵带位于脸侧并向上延伸;联合平移和缩放,保证十字在主体内相交。整段带与模糊底均应离开脸部安全区,不能仅依靠最终挖洞来掩盖穿脸布局。
- 输出前检查同色系深色、脸部锚点、交叉位置、完整保护、文字可读性、边框内边距及纹理完整性。本次示例沿用已有识别并人工修正;新提示词另需跨画作效果评估。
深色统一与实验入口手动调整(v4)
维护者进一步要求:缎带、爱心、右侧方形图标也统一到画作主色的深色,爱心缩为之前的 70% 并略上移。因此默认规则改为 frame、footer-signature、各类 ribbon、heart-signature、small-seal 共享深色;仅改变 RGB,保留素材 alpha、正常混合和局部背景柔化。细小纹理和 FOR DISPLAY ONLY 保留原色。爱心起始宽度变为脸宽的 0.45–0.63 倍,仍保持主脸左下方及安全距离。
/watermark-lab 继续作为 P15-04a 的预设分析/合成实验入口,不声称完成 P15-02~04 的正式画板文档与工程契约。沿用现有七字段 placement 和浏览器合成器,增加轻量布局校正:
WatermarkLab负责入口编排;useWatermarkLab持有 placement、选择和最多 50 步的布局调整历史。WatermarkPresetControls接收预设、布局、选择和状态,发出选中、添加、修改、移除和历史动作;展开当前水印属性,可调位置、宽度、旋转、透明度和允许换色的素材颜色,支持恢复原色和缩小为 70%。WatermarkPreview负责图片与保护区展示;WatermarkPlacementOverlay只维护单次指针手势草稿,发出选中和最终变换。拖动时显示边界,松开才重新合成,避免每个 pointermove 都对 2000 万像素进行 PNG 编码。Esc/pointercancel 放弃草稿,保护区仍由合成器保留。- 点击普通水印拖动、右下角等比缩放、方向键 1px/Shift 10px 微调、Delete 移除;画布水印聚焦时 Ctrl/Cmd+Z 与 Shift+Z 撤销/重做。全屏纹理与边框从列表选择,保持铺满/贴边的特定布局约束。
- 可不调用 AI,直接从素材列表添加水印。切换分析服务或编辑规则会取消旧请求,但保留当前手动布局;换画作或换素材包会重置布局与历史。素材启用勾选仍用于分析输入,改变勾选会明确提示重置布局。
本次 4800×4300 示例复用已有识别:深色 #304050;爱心宽度由 0.10 调为 0.07,中心横坐标保持,顶部由 0.357 上移为 0.352。没有额外模型调用或账本扣点。实验入口编辑不等同于私有素材云同步或正式可编辑工程保存。
Saier 图层工作台(2026-09-28)
/watermark-lab 新增「在 Saier 工作台编辑图层」入口,保留当前画作、素材实例、颜色及保护区域,使用原生 Painter 画布、选择框、缩放平移和变换历史。普通水印可拖动、等比缩放、旋转,右侧属性支持位置、尺寸、透明度、颜色和 70% 缩放;方向键移动 1px,Shift 移动 10px,Ctrl/Cmd+Z 与 Shift+Z 撤销/重做。原图固定,边框与全屏纹理保持各自布局约束。
WatermarkWorkspace适配器由 Saier 文档保存实际几何与透明度,素材描述保存换色及程序化布局参数;Vue 只展示快照并发送操作。确认调整一次回填实验入口的布局历史,取消则保留原布局。Painter.setDocumentPreview()是显示层扩展:宿主合成的预览置于文档空间,保留原生变换手柄,清除预览或切换文档恢复原显示。该接口不改变原生工程和导出。工作台继续用水印合成器处理局部背景柔化、线性光、叠加和脸部 RGBA 保护,避免使用普通图片图层导出而丢失 PSD 近似效果。- 交互预览最长边 1440px,变更后合并更新;PNG 下载仍按原图尺寸完整合成,不受缩放影响。大图编辑预览与全尺寸效果可能存在采样差异,不承诺所有设备实时性能。
- 「保存工作文件」保存原图、内嵌素材、效果、布局和保护区;「打开水印工作文件」原子校验后直接进入工作台。
saier.watermark-workfilev1 是此预设工作流的本地交换文件,不升级saier.project,不代表完成 P15-02 的通用素材文档或 PSD 互通。读取只接受内嵌 PNG,限制包体、单边与像素预算,不请求远程素材 URL。 - 浏览器回归覆盖原生画布拖动、微移、撤销重做、换色、保存重开和回填;像素回归覆盖初始合成不变、保护区、原尺寸导出、工作文件往返及显示预览切换后的原生文档隔离。当前 4800×4300 样例工作文件只存放于用户本机,未添加至仓库或公网站点。
工作台 PSD 导出与 Krita 互通(2026-09-28)
工作台新增「下载分层 PSD」,复用 ag-psd 31.0.2 写出 RGB、8 位、RLE 压缩的普通 PSD。导出器独立于 Vue 与 Painter,使用当前原图、已确认的布局与保护区域,不调用 AI。
- 原图、各水印实例和每个局部背景柔化效果分别输出像素图层;普通素材按旋转后的边界裁切,保存偏移。位移/缩放/旋转和换色烘焙到各层像素,透明度和正常/叠加/线性光作为独立 PSD 属性保留,只应用一次。
- 背景柔化层全部置于水印下方,与网页两遍合成顺序一致;柔化来自原图的局部模糊像素,不是 Krita 实时滤镜。移动缎带后可同时移动对应柔化层,改变模糊半径须重新处理效果。
- 与保护区相交的图层附带可编辑的灰度透明度蒙版,含短边 2% 安全边距。水印本身保留完整像素,保护不烘焙成不可恢复的空洞。Krita 中后续移动图层或蒙版仍需人工检查避脸关系,不运行网页的动态保护逻辑。
- PSD 合成预览使用同一原尺寸合成器;单边上限 8192、总像素 3200 万,待导出像素图层累计预算 1.6 亿。普通图层裁切、共享相同保护蒙版与释放临时画布降低开销,但大图导出仍需要足够内存。
- 文字和图标都是像素水印,支持移动、缩放、调色和透明度;不承诺直接编辑文字内容、智能对象或实时样式。正式画板通用 PSD 保存、复杂 PSD 往返及 Photoshop 验收仍不在此交付范围。
实际用本机 Krita 5.3.2 读取 4800×4300 样例 PSD,并另存 PNG 与 KRA:14 个像素图层(原图 + 9 个水印 + 4 个柔化层)和 5 个透明度蒙版保留,细纹理为 overlay / 105,重复小字为 linear light / 255。Krita 重合成 PNG 相对网页 v4 PNG 的 RGBA 平均绝对差 0.0764、最大差 3(0–255),没有大于 10 的差异像素;因此承诺此样例视觉近似一致,不宣称跨合成器逐像素相同。PSD 为 133251079 字节,原素材没有公开上传。能力边界参见 Krita 官方 PSD 文档。
主画板插件面板(2026-09-28)
水印工作流现可从主入口 / 的「插件 → 水印」开启,作为现有面板系统的扩展。桌面支持拖动、折叠及合并标签,手机使用底部面板;本次没有新增路由。/watermark-lab 保留旧实验入口兼容。
editor-plugins/registry.ts注册可信内置插件的 ID、标题、图标、动态组件。主界面通过plugin:<id>动态插槽注入桌面/手机 Shell,开关单独保存在本机。后续插件优先贡献面板及文档适配器,不复制页面或另起 Painter。本接口不执行用户上传的 JavaScript。- 水印面板可直接读取当前画布、导入图片/预设或打开已有工作文件,编辑 AI 服务和布局规则,再在同一个 Painter 内创建水印文档标签。已是水印文档时读取未合成的原图和当前布局,避免重复叠加。AI 按钮仅分析,应用布局需要明确点击;不会在开启面板时收费调用。
useWatermarkDocuments按文档 ID 持有WatermarkWorkspace适配器;主画布、原生选择变换与历史共用,不创建第二个画布工作台。关闭插件仅关闭面板,已打开的文档及编辑仍保留;重新开启可继续调整。关闭文档才释放对应适配器。切回绘画标签恢复原图层与绘画面板。主画布与 Activity 工作区通过 Teleport 保持节点身份,切换桌面/手机外壳不再重建 canvas。- 保存命令在水印文档中导出包含素材、保护区和布局的工作文件;PNG/PSD 仍由原有全尺寸合成器导出,保留混合模式和局部背景柔化。水印文档暂不进入普通工程草稿、绘画云同步或协作房间流程,防止把仅用于交互的代理图层误存成完整作品。主画板现已补齐独立的水印本地草稿恢复(见下节),长期备份仍通过下载工作文件完成。
- 绘画/滤镜/普通图层增删命令在水印文档中受限,水印从专用图层列表和属性面板调整;切回绘画文档可继续绘制。打开大文件和导出期间暂时锁定文档切换,防止异步导入落到其他画布。
- AI 服务选择和用户规则可在本机记忆;配对凭据、原图和私有预设不写入这些 localStorage 配置。关闭面板或切换文档取消等待中的分析。云端已经提交的请求仍遵循统一 Runtime 的结算规则。
此接入沿用程序化预设适配器和 v1 工作文件,尚未升级通用 saier.project 文档协议。注册新插件仍需代码接入;面板内的素材、AI 规则与逐层参数可以由用户配置。
自定义素材与 Drive 私有库
主界面「插件 → 水印 → 素材、布局与 AI 配置 → 我的水印」支持导入 PNG / JPEG / WebP, 选择素材用途及是否随画面调整颜色。单文件上限 25 MB、最长边 8192px,每套最多 12 个素材, 合计 3200 万像素。新增素材保留已有布局;所有图片转换为内嵌 PNG,随预设与工作文件保存。
「Drive 私有素材库」复用云乐坊登录及 @yunlefun/assets 协议。读取、搜索、分页、选用和明确 上传均走独立 saier-assets-api 云函数;文件直接通过短期签名上传至统一私有存储。不会自动 上传画作,也不会把素材加入公开预设。角色、混合效果及布局继续由 Saier 预设管理。
服务端只接受网关 UID,Drive 再执行 owner / tenant / space 隔离。客户端每次请求检查真实 会话,换号立即清除云端列表;已明确选入当前本地文档的图片是文档内容,不会在退出时删除。 下载校验字节数与 SHA-256,不持久化签名 URL。完成上传失败可以单独重试确认。
2026-09-28 已完成 Saier 独立 consumer 注册、生产读写与网页端真实验收:从 Saier 主页面 登录、上传 32 × 32 合成 PNG、云端重新选用,并在 Drive 查看同一私有图片。发布记录见下方 README。 现有 Drive 凭据固定 tenant/space,多用户个人库须逐空间授权或由 Drive 补齐按用户的连接 解析,不能把单用户 credential 当成全站授权。详细上线清单见仓库 cloudbase/functions/saier-assets-api/README.md。
水印本地草稿恢复(2026-10-05)
主入口 / 的水印文档在编辑停顿约 700 ms 后自动保存。水印面板显示等待、保存中、已保存和失败状态,也提供「立即保存草稿」/「重试保存草稿」。草稿成功不等于已下载工作文件,不清除文件标签的未保存标记。
- 复用边界:复用
serializeWatermarkWorkfile()/readWatermarkWorkfile(),以及普通工程草稿的 IndexedDB 事务完成工具。保留独立的水印存储库saier-watermark-drafts,不占用普通绘画草稿的current记录,也不调用Painter.exportProject()保存代理图层。原有绘画草稿的格式及迁移流程保持兼容。 - 保存内容:原始画作 PNG、所有内嵌素材(含未启用素材)、素材效果、规则、布局及保护区,另存文档名和选中水印的序号。恢复时按序号重建选中层,不持久化临时 Painter 图层 ID。当前工作台的素材在文档生命周期内不变,因此原图仅编码一次,后续保存更新布局和编辑状态。
- 恢复入口:重新打开后检测到草稿会开启水印面板,逐份显示名称和保存时间;用户点击「恢复草稿」后才创建文档。恢复之前完整解码并校验素材和布局。关闭面板或文档保留恢复副本;打开同名工作文件会获得独立草稿 ID。切换文档不改变待保存快照所属的文档。
- 丢弃:明确点击「丢弃草稿/丢弃本地草稿」并确认后,只删除该文档的恢复副本。当前画面保留,视图变化或刷新不会立即重建已丢弃的副本;再次编辑或主动保存后可重新生成。删除失败保留记录并提示重试。
- 失败保护:写入前复用工作文件的完整校验。每文档当前版和上一有效版在同一 IndexedDB 事务内替换,以事务提交作为保存成功标准。配额不足、序列化/校验失败、事务中止不会覆盖已有版本,也不自动清理其他文档。最新版本损坏时回退到上一有效版并明确提示;两版都损坏时保留记录,提供丢弃操作。写入时用修订号检查并发修改,其他页面改写或删除同一草稿时拒绝静默覆盖。
本地恢复限制:
- 仅适用于已在主画板应用的水印文档;素材配置面板中尚未应用的准备工作,以及
/watermark-lab实验页,不纳入自动恢复。 - 仅限同一浏览器配置、同一站点来源(域名、协议、端口);不上传云端,不跨设备同步。隐私窗口、浏览器清理/驱逐站点数据或存储权限关闭可能使草稿不可用。
- 应等待「已保存到本机」再刷新或退出。切到后台会尝试刷新待保存任务,但浏览器突然关闭、崩溃或断电时,最后一次尚未提交的编辑无法保证保存。旧的已提交版本仍可恢复。
- 不恢复撤销/重做历史、正在进行的指针手势、视口位置和临时 AI 请求;恢复后自动适配视口。配对码、登录令牌及签名下载 URL 不随草稿持久化。
- 沿用工作文件上限:100 MiB 文件、原图最长边 8192、总计 3200 万像素;素材上限沿用预设读取器。两个版本及内嵌 PNG 会占用额外磁盘和内存,实际可用空间取决于浏览器配额。存储失败时可下载完整工作文件备份。
- 多页面同时恢复同一草稿后,后写入者可能遇到修订冲突;先下载当前工作文件,再重新打开页面选择需要的版本。没有自动合并,也不承诺本地草稿是长期备份。
回归入口:
site/app/features/watermark/draft.browser.spec.ts:真实 IndexedDB 事务中止、保存前校验、多文档隔离、RGBA 保护、损坏回退及并发修订冲突。site/app/editor-plugins/watermark/useWatermarkDrafts.browser.spec.ts:异步写入期间连续编辑、回到旧状态、失败重试、丢弃与待写入队列的顺序。e2e/watermark-drafts.pw.ts:编辑两份包含素材、效果和保护区的作品,切换/刷新/恢复后比较完整配置与 PNG 字节;模拟配额不足,刷新恢复上一成功版本;验证损坏提示和明确丢弃。- 运行
pnpm test run site/app/features/watermark site/app/editor-plugins/watermark test/project-draft.test.ts test/project-draft-navigation.test.ts test/watermark-analysis.test.ts test/watermark-preset.test.ts;运行pnpm test:e2e e2e/watermark-drafts.pw.ts e2e/watermark-editor.pw.ts e2e/watermark-lab.pw.ts。端到端测试在test-results/生成已保存、恢复入口、恢复后及保存失败四张操作截图。
本轮验证:36 项相关单元/浏览器回归、10 项水印端到端用例通过;根目录 lint、TypeScript、site 的 Vue 类型检查及 site 生产构建通过。生产构建仍有依赖 sourcemap/PURE 注释和大包体提示。测试使用合成素材,不涉及个人画作或云端上传。