功能一:图片编辑器入口优化 - 支持先打开编辑器再上传图片 - 新增拖拽上传功能 - 新增粘贴上传功能 (Ctrl+V) 功能二:场景裂变 - 新增场景裂变弹窗组件 - 支持产品图批量融合到多个场景 - 每个场景独立配置补充关键词 - 并发处理提高效率 - 支持单个重新生成和全部下载 - 生成结果自动保存到相册 管理员配置: - 新增场景裂变配置面板 - 支持自定义默认提示词 - 支持配置最大场景数量 - 支持功能开关 新增文件: - app/api/scene-fusion/route.ts - app/api/scene-fusion/config/route.ts - components/scene-fusion-dialog.tsx - docs/图片编辑器功能升级规划.md
15 KiB
15 KiB
图片编辑器功能升级规划文档
概述
本文档规划两个新功能:
- 图片编辑器入口优化 - 允许用户先打开页面再上传图片
- 场景裂变功能 - 批量将产品图替换到多个场景图中
功能一:图片编辑器入口优化
当前问题
- 用户点击顶部导航栏的「图片编辑器」按钮时,必须先上传图片才能打开界面
- 用户体验不佳,无法预览编辑器界面
解决方案
方案 A:两步式交互(推荐)
- 用户点击「图片编辑器」按钮
- 打开图片编辑器页面/弹窗
- 页面中显示上传区域,用户可以:
- 拖拽上传图片
- 点击选择图片
- 粘贴图片
- 上传后进入编辑模式
UI 设计
┌─────────────────────────────────────────────────────────┐
│ 图片编辑器 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ │ │
│ │ 📷 拖拽图片到此处或点击上传 │ │
│ │ │ │
│ │ 支持 JPG、PNG、WebP 格式 │ │
│ │ 最大 10MB │ │
│ │ │ │
│ └─────────────────────────────────────────┘ │
│ │
│ [选择图片] [从剪贴板粘贴] │
│ │
└─────────────────────────────────────────────────────────┘
技术实现
- 修改
ImageAnnotator组件,支持无图片时显示上传界面 - 修改导航栏点击事件,直接打开编辑器弹窗
- 添加拖拽上传、点击上传、粘贴上传功能
功能二:场景裂变
功能描述
用户上传一张产品图(图A),再上传 1-10 张场景参考图(B1-B10),系统自动将产品图批量融合到每个场景中。
用户流程
1. 用户上传产品图 A(必须)
2. 用户上传场景图 B1-B10(至少1张,最多10张)
3. 用户可选填补充关键词
4. 点击「开始裂变」
5. 系统依次调用阿里生图 API:
- 图A + 图B1 → 生成 AB1
- 图A + 图B2 → 生成 AB2
- ...
- 图A + 图B10 → 生成 AB10
6. 显示所有生成结果,支持下载
UI 设计
┌─────────────────────────────────────────────────────────────────┐
│ 场景裂变 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 产品图 A (必须上传) │ │
│ │ ┌─────────┐ │ │
│ │ │ │ [上传产品图] [更换] │ │
│ │ │ 产品 │ │ │
│ │ │ │ │ │
│ │ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 场景参考图 (1-10张) [添加场景] │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ 场景 1 [删除] │ │ │
│ │ │ ┌───────┐ 补充关键词: │ │ │
│ │ │ │ B1 │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ │ │ 例如:放在木质桌面上 │ │ │ │
│ │ │ └───────┘ └─────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ 场景 2 [删除] │ │ │
│ │ │ ┌───────┐ 补充关键词: │ │ │
│ │ │ │ B2 │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ │ │ 例如:放在白色大理石台面上 │ │ │ │
│ │ │ └───────┘ └─────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ... (更多场景) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 默认提示词:将图1的产品替换到图2的场景中,保持图1产品的外观、 │
│ 颜色和细节不变,自然融合到图2的环境中。 │
│ │
│ [开始裂变] (已添加 2 个场景) │
│ │
├─────────────────────────────────────────────────────────────────┤
│ 生成结果: │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 场景1: AB1 │ │ 场景2: AB2 │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ ✓完成 │ │ │ │ 生成中..│ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │
│ │ [下载] [重新生成]│ │ [下载] [重新生成]│ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ [全部下载] [保存到相册] │
│ │
└─────────────────────────────────────────────────────────────────┘
技术实现
1. 数据结构
// 场景项数据结构
interface SceneItem {
id: string; // 唯一标识
image: string; // 场景图 URL 或 Base64
customPrompt: string; // 该场景的补充关键词
status: 'pending' | 'processing' | 'completed' | 'failed';
result?: string; // 生成结果图片 URL
error?: string; // 错误信息
}
// 场景裂变状态
interface SceneFusionState {
productImage: string | null; // 产品图 A
scenes: SceneItem[]; // 场景列表 (1-10)
isProcessing: boolean; // 是否正在处理
currentIndex: number; // 当前处理的场景索引
}
2. 新建组件
components/scene-fusion-dialog.tsx- 场景裂变弹窗组件
3. API 调用逻辑
// 调用现有的阿里生图 API
// 每次请求:产品图A + 场景图Bn + 提示词
const defaultPrompt = "将图1的产品替换到图2的场景中,保持图1产品的外观、颜色和细节不变,自然融合到图2的环境中。";
async function generateSceneFusion(
productImage: string, // 产品图 A
sceneImage: string, // 场景图 Bn
customPrompt?: string // 该场景的补充关键词(每个场景独立)
) {
// 组合提示词:默认提示词 + 该场景的补充关键词
const prompt = customPrompt
? `${defaultPrompt} ${customPrompt}`
: defaultPrompt;
// 调用阿里生图 API(使用现有的 alibaba-image provider)
// 输入:[productImage, sceneImage] + prompt
// 输出:融合后的图片
}
// 批量并发处理所有场景
async function processAllScenes(
productImage: string,
scenes: SceneItem[],
onComplete: (results: SceneItem[]) => void
) {
// 1. 显示动态占位卡片(使用现有的 ImageGenerationLoading 组件)
// 2. 并发发出所有请求
const promises = scenes.map(async (scene, index) => {
try {
const result = await generateSceneFusion(
productImage,
scene.image,
scene.customPrompt // 使用该场景独立的补充关键词
);
return { ...scene, status: 'completed' as const, result };
} catch (error) {
return { ...scene, status: 'failed' as const, error: error.message };
}
});
// 3. 等待所有请求完成
const results = await Promise.all(promises);
// 4. 同时显示所有结果
onComplete(results);
// 5. 保存到用户相册和生图记录
await saveToGalleryAndRecords(results);
}
// 保存结果到相册和生图记录
async function saveToGalleryAndRecords(results: SceneItem[]) {
const successResults = results.filter(r => r.status === 'completed' && r.result);
for (const result of successResults) {
// 调用现有的保存图片 API
await fetch('/api/gallery', {
method: 'POST',
body: JSON.stringify({
imageUrl: result.result,
// ... 其他参数
})
});
}
}
4. 批量处理策略
- 并发处理:同时发出所有请求,提高处理速度
- 等待显示:等待所有图片生成完成后,同时显示结果
- 加载状态:使用现有的动态占位卡片显示等待状态
- 错误处理:单张失败不影响其他图片,显示失败原因,支持重新生成
- 结果保存:✅ 生成的图片保存到用户相册和生图记录
4. 入口位置
- 图片编辑器页面顶部工具栏添加「场景裂变」按钮
- 点击打开场景裂变弹窗
文件修改清单
功能一:图片编辑器入口优化
| 文件 | 修改内容 |
|---|---|
components/image-annotator.tsx |
支持无图片时显示上传界面 |
components/multimodal-input.tsx |
修改图片编辑器按钮点击逻辑 |
功能二:场景裂变
| 文件 | 修改内容 |
|---|---|
components/scene-fusion-dialog.tsx |
新建场景裂变弹窗组件 |
components/image-annotator.tsx |
添加「场景裂变」按钮入口 |
app/api/scene-fusion/route.ts |
新建场景裂变 API(可选,也可直接前端调用现有 chat API) |
时间估算
| 功能 | 预计工时 |
|---|---|
| 功能一:图片编辑器入口优化 | 1-2 小时 |
| 功能二:场景裂变 | 3-4 小时 |
| 测试和调试 | 1 小时 |
| 总计 | 5-7 小时 |
待确认事项
-
场景裂变的默认提示词:
- 当前设计:
将图1的产品替换到图2的场景中,保持图1产品的外观、颜色和细节不变,自然融合到图2的环境中。
- 当前设计:
-
每个场景的补充关键词:
- ✅ 已确认:每个场景图独立配置补充关键词
- 用户可以为每个场景单独填写补充描述
-
最大场景图数量:
- ✅ 已确认:最多 10 张
-
生成图片数量:
- 当前设计:每个场景生成 1 张
-
并发处理:
- ✅ 已确认:并发处理(同时发出所有请求)
- 等待所有图片生成完成后,同时显示结果
- 等待过程中使用现有的动态占位卡片
-
结果保存:
- ✅ 已确认:保存到用户相册
- ✅ 已确认:保存到生图记录
-
入口位置:
- ✅ 已确认:场景裂变入口放在图片编辑器工具栏中
-
重新生成:
- ✅ 已确认:支持对单个失败/不满意的场景重新生成
请确认以上规划,确认后我将开始开发。