diff --git a/.memory/worklog.json b/.memory/worklog.json index c96da8b..cf3b04c 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -425,6 +425,32 @@ "type": "session-heartbeat", "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:feat: add anchored image pipeline", "files_changed": 1 + }, + { + "ts": "2026-05-19T10:02:27+08:00", + "type": "commit", + "message": "auto-save 2026-05-19 10:02 (~2)", + "hash": "9a251ee", + "files_changed": 2 + }, + { + "ts": "2026-05-19T10:03:36+08:00", + "type": "commit", + "message": "docs: record anchored image pipeline", + "hash": "5ff7758", + "files_changed": 0 + }, + { + "ts": "2026-05-19T02:09:59Z", + "type": "session-heartbeat", + "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:docs: record anchored image pipeline", + "files_changed": 1 + }, + { + "ts": "2026-05-19T02:19:59Z", + "type": "session-heartbeat", + "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:docs: record anchored image pipeline", + "files_changed": 1 } ] } diff --git a/HANDOFF_IMAGE_PIPELINE.md b/HANDOFF_IMAGE_PIPELINE.md index a45befe..34d7e4e 100644 --- a/HANDOFF_IMAGE_PIPELINE.md +++ b/HANDOFF_IMAGE_PIPELINE.md @@ -440,3 +440,228 @@ L0 意向图 ──→ L1 白底锚图 ──┬──→ 专利主图 ──→ 6. Seedance 视频参考用的是宣发白底图 实测时拿一张复杂玩具图(带帽子、背包、标牌)跑全链路,所有图角色一致、配件清晰、视频与电商图一致。 + +--- + +## 8. 上传图入口的三种模式(二创 / 复刻 / 复刻+补全) + +### 8.1 场景 + +用户的实际使用场景不止"从一句话开始",还有: + +- **已经有玩具/IP 图**(手稿、成品照、参考海报、其他设计师的稿) +- **只缺某些视角**(手上有正面图,要补侧/背/俯视) +- **想做风格化变体**(已有原型,但要换成赛博朋克版/绒线编织版/迪士尼风) + +当前 `PromptPanel` 是 prompt-first,上传图只是被丢进 prompt 末尾当文本提示(见 Gap 1),**完全没真正参与生成**。需要重新设计上传图的语义。 + +### 8.2 三种入口模式 + +#### Mode A · 二创(Remix) + +``` +用户:[上传图 1-4 张] + [选风格 + 描述变化方向] +系统:保留核心识别(轮廓/五官/品牌符号),按用户要求做风格/材质/配色变化 +输出:4-12 张候选变体 +后续:选中 → Lock → 正常 Pack 流程 +``` + +技术实现: +- 走 `/images/edits` multipart,传第 1 张为主参考图 +- prompt 拼接:`{风格 promptBlock} + {用户变化描述} + 强制 negative:不改变身体比例、五官相对位置、品牌符号、配件轮廓` +- `n=4/8/12` 生成多张候选 + +#### Mode B · 复刻(Replicate) + +``` +用户:[上传图 1 张],标记为"主体图" +系统:跳过批量生图,直接以这张图作为 L0 锚图 + → 立刻做 L1 净化(白底、保真) + → 调 Vision 识别配件、推断 CharacterSpec + → 用户确认后进入 Pack +输出:完整专利/配件/生产/宣发包 +``` + +适用场景:手上已有终稿原画,只需要把它"扩展"成完整素材包。 + +技术实现: +- 上传图后跳过 `/api/generate`,直接构造一个 `GenImage` 写入 session,status='selected' +- 自动触发 `/api/character/cleanup` 生成 L1 +- 自动触发 `/api/character/lock`(CharacterSpec 让 Vision 推断,用户可编辑) +- 用户点"进入 Pack"才开始 pack 生成 + +#### Mode C · 复刻 + 补全(Extend) + +``` +用户:[上传图 1-4 张],每张标记为"主体 / 同角色另一视角 / 配件孤立图" +系统:先把"主体"作为 L0 + 已有视角直接占用对应 slot(如上传了"正面图" → 占用 patent_front) + 缺失的 slot 才调 API 生成 +输出:节省 80% 算力,前后一致性最强 +``` + +适用场景:用户已经手工画了正面+背面,要补侧视图+俯视图+配件六视图。 + +技术实现: +- 上传时弹出 tagging UI,让用户选每张图的"槽位" +- 后端在 `generateAssetPack` 前先合并预占的 slot +- 已占 slot 跳过 API 调用,直接复用上传图 + +### 8.3 UI 入口设计 + +`PromptPanel` 改成 3 个 tab: + +``` +┌─────────────────────────────────────────┐ +│ [💡 想法] [🎨 二创] [📐 复刻] │ +├─────────────────────────────────────────┤ +│ Mode A 二创 tab 内容: │ +│ - 上传图(1-4 张,第 1 张为主参考) │ +│ - 风格选择(图卡,引用 §3 风格库) │ +│ - 变化方向描述(textarea) │ +│ - 数量 4/8/12 │ +│ - [生成变体] │ +└─────────────────────────────────────────┘ +``` + +Mode B 和 Mode C 共享一个 tab,差异在上传后的处理: +- 只传 1 张且不标记 → Mode B +- 传多张并标注槽位 → Mode C + +### 8.4 上传图的元数据(共用) + +每张上传图都要附带: + +```typescript +export type UploadedImage = { + id: string; + url: string; // /api/img/uploads/xxx.png + filename: string; + uploadedAt: number; + role: 'reference' // 二创模式的灵感图 + | 'subject' // 复刻模式的主体 + | 'view-front' // 已有的视角,占用对应 slot + | 'view-back' + | 'view-left' + | 'view-right' + | 'view-top' + | 'view-bottom' + | 'accessory-isolated' // 配件孤立图 + | 'accessory-named'; // 已命名的配件图 + accessoryName?: string; // 仅 accessory-* 时有效 + needsCleanup: boolean; // 是否需要先净化才能用 +}; +``` + +存储路径:`data/uploads/`。 + +### 8.5 新增 API + +``` +POST /api/uploads + Body: multipart, image file + role + accessoryName? + Resp: UploadedImage + +POST /api/projects/from-upload + Body: { uploadedImages: UploadedImage[], mode: 'remix' | 'replicate' | 'extend', + remixPrompt?: string, styleId?: string, count?: number } + Resp: + - mode=remix: { sessionId, images } (4-12 变体) + - mode=replicate: { sessionId, characterSpec, l1AnchorUrl } + - mode=extend: { sessionId, characterSpec, l1AnchorUrl, preFilledSlots } + +POST /api/character/lock-from-upload + Body: { sessionId, subjectImageId } + Resp: 调 Vision 推断 CharacterSpec +``` + +### 8.6 Vision 推断 CharacterSpec + +Mode B 和 C 没有原始 prompt,需要 GPT Vision 看图推断。 + +`src/lib/providers.ts` 新增: + +```typescript +export async function inferCharacterSpecFromImage(opts: { + imageUrl: string; + userHint?: string; // 用户可选输入"这是我的 IP, 名字叫小桔" +}): Promise +``` + +实现: +- 走 `/responses` + vision input +- prompt = "你是玩具产品经理,根据图片推断 CharacterSpec。严格 JSON,包含 name/oneLiner/speciesShape/bodyRatio/faceFeatures/colorPalette/materials/accessories/signatureElements/patentFocus/negativePrompt 字段" +- 如果 userHint 有值,name 用它,否则让 GPT 生成 + +### 8.7 复刻模式的 L1 净化注意事项 + +复刻模式比"从 prompt 开始"对净化要求更高:**不能改任何角色细节**。 + +`/api/character/cleanup` 在复刻模式下要使用更强的约束 prompt: + +``` +保持原图完全一致,仅做以下修改: +1. 把背景换成纯白色 +2. 去除任何水印、文字、价格标签、网页 UI 元素 +3. 居中并适当裁剪到正方形构图 + +绝对不要修改: +- 角色五官、表情、姿态 +- 主体配色、材质、纹理 +- 配件位置、轮廓、细节 +- 任何品牌符号(如胸前 logo) + +输出风格:商业产品图,柔和均匀打光,无阴影。 +``` + +可以在 `cleanup` API 里加 `preserveLevel: 'strict' | 'normal'` 参数。 + +### 8.8 已有视角槽位的智能匹配(Mode C) + +用户上传时标的 `role: view-front` 等,直接 1:1 占用专利包/配件包的对应模板: + +| 上传 role | 占用模板 ID | +|---|---| +| `view-front` | `patent_front` + `acc_front`(如是配件) | +| `view-back` | `patent_back` | +| `view-left` | `patent_left` | +| `view-right` | `patent_right` | +| `view-top` | `patent_top` | +| `view-bottom` | `patent_bottom` | +| `accessory-isolated` | 该配件的 `isolated_anchor` | + +`generateAssetPack` 在生成前先检查 session.preFilledSlots,已占用的 template 直接复用上传图,不调 API。 + +### 8.9 合规和版权提示 + +UI 上传图区域要醒目提示: + +> ⚠️ 上传图必须为你拥有或有合法授权使用的素材。请勿上传迪士尼、三丽鸥、泡泡玛特等已注册 IP 的图像;生成结果用于专利申请时,需自行确认不与他人在先权利冲突。 + +后端可选做基础检测: +- 调 GPT Vision 看图,若识别为已知品牌 IP("Hello Kitty"、"Mickey Mouse"、"Labubu")→ 阻止上传并给出明确警告 +- 这一步初版可不做,但要在 UI 留位 + +### 8.10 实施 Checklist 增量 + +在 §4 Checklist 之外,额外加: + +- [ ] 8.A 上传 API + 存储 `data/uploads/` +- [ ] 8.B `PromptPanel` 改 3-tab:想法 / 二创 / 复刻 +- [ ] 8.C Mode A(二创):multipart + `/images/edits` 批量变体 +- [ ] 8.D Mode B(复刻):跳过批量生图,直接 lock + cleanup +- [ ] 8.E `inferCharacterSpecFromImage` Vision 推断 +- [ ] 8.F Mode C:上传图 role 标注 UI + `preFilledSlots` 合并 +- [ ] 8.G cleanup 加 `preserveLevel` 参数,复刻模式用 strict +- [ ] 8.H 版权合规提示 UI + +### 8.11 优先级建议 + +最实用顺序: + +1. **Mode B 复刻**(最常用:用户已有玩具图想做素材包) +2. **Mode A 二创**(次常用:用户有概念图想做风格变体) +3. **Mode C 复刻+补全**(高级:用户有部分视图想补齐) + +如果只做一个,先做 Mode B —— 它对"前后一致"的帮助最直接,相当于直接拿用户图当 L0 锚图,跳过最容易漂移的"prompt → 意向图"阶段。 +