diff --git a/docs/POSTER_FABRIC_PLAN.md b/docs/POSTER_FABRIC_PLAN.md new file mode 100644 index 0000000..04f757e --- /dev/null +++ b/docs/POSTER_FABRIC_PLAN.md @@ -0,0 +1,347 @@ +# 海报生成方案 - Fabric.js 前端渲染 + +## 背景 + +当前方案在 Python 端下载图片并渲染海报,存在以下问题: +- 图片下载耗时长 +- 输出静态 PNG,用户无法编辑 +- 服务端渲染压力大 + +## 新方案概述 + +**Python 端只生成文案和布局参数,输出 fabric.js JSON,前端负责渲染和合成。** + +``` +┌─────────────┐ JSON ┌─────────────┐ Canvas ┌─────────────┐ +│ Python AI │ ─────────▶ │ Frontend │ ──────────▶ │ 用户编辑 │ +│ 文案生成 │ │ fabric.js │ │ 导出图片 │ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +## 数据流 + +### 1. 输入 (用户请求) + +```json +{ + "category": "民宿", + "name": "山舍云端民宿", + "description": "藏在莫干山的治愈系民宿", + "price": "458元/晚", + "location": "莫干山", + "features": "独立庭院, 手冲咖啡, 山景露台", + "image_url": "https://example.com/image.jpg" +} +``` + +### 2. Python 输出 (Fabric.js JSON) + +```json +{ + "version": "1.0.0", + "canvas": { + "width": 1080, + "height": 1440, + "backgroundColor": "#FFF5F0" + }, + "layout": "hero_bottom", + "theme": "sunset", + "content": { + "title": "去了莫干山才知道...", + "subtitle": "藏在山里的治愈系民宿,推开窗便是云海", + "highlights": ["独立庭院", "手冲咖啡", "山景露台"], + "details": ["管家式服务超贴心", "有机早餐太惊艳"], + "price": "¥458", + "price_suffix": "/晚", + "tags": ["莫干山民宿", "周末度假"] + }, + "objects": [ + { + "id": "background_image", + "type": "image", + "src": "https://example.com/image.jpg", + "left": 0, + "top": 0, + "width": 1080, + "height": 1440, + "scaleX": 1, + "scaleY": 1 + }, + { + "id": "gradient_overlay", + "type": "rect", + "left": 0, + "top": 800, + "width": 1080, + "height": 640, + "fill": { + "type": "linear", + "coords": {"x1": 0, "y1": 0, "x2": 0, "y2": 640}, + "colorStops": [ + {"offset": 0, "color": "rgba(89,66,52,0)"}, + {"offset": 0.5, "color": "rgba(89,66,52,0.8)"}, + {"offset": 1, "color": "rgba(89,66,52,1)"} + ] + } + }, + { + "id": "title", + "type": "textbox", + "text": "去了莫干山才知道...", + "left": 48, + "top": 880, + "width": 984, + "fontSize": 80, + "fontFamily": "PingFang SC", + "fontWeight": "bold", + "fill": "#FFFFFF", + "shadow": "rgba(0,0,0,0.3) 2px 2px 4px" + }, + { + "id": "subtitle", + "type": "textbox", + "text": "藏在山里的治愈系民宿,推开窗便是云海", + "left": 48, + "top": 980, + "width": 984, + "fontSize": 32, + "fontFamily": "PingFang SC", + "fill": "rgba(255,255,255,0.85)" + }, + { + "id": "price_bg", + "type": "rect", + "left": 36, + "top": 1280, + "width": 180, + "height": 60, + "rx": 12, + "ry": 12, + "fill": "rgba(255,255,255,0.2)" + }, + { + "id": "price", + "type": "text", + "text": "¥458", + "left": 48, + "top": 1290, + "fontSize": 48, + "fontFamily": "PingFang SC", + "fontWeight": "bold", + "fill": "#FFFFFF" + }, + { + "id": "price_suffix", + "type": "text", + "text": "/晚", + "left": 160, + "top": 1308, + "fontSize": 24, + "fontFamily": "PingFang SC", + "fill": "rgba(255,255,255,0.8)" + } + ] +} +``` + +## 架构设计 + +### Python 端 + +``` +domain/aigc/engines/ +├── poster_smart_v1.py # 当前:AI文案 + Python渲染 +└── poster_smart_v2.py # 新增:AI文案 + Fabric JSON输出 +``` + +#### PosterSmartEngineV2 职责 + +1. **AI 文案生成** - 调用 LLM 生成标题、副标题、亮点等 +2. **布局推荐** - 根据内容类型推荐布局 +3. **主题推荐** - 根据内容类型推荐配色 +4. **Fabric JSON 生成** - 输出标准 fabric.js 格式 + +```python +class PosterSmartEngineV2(BaseEngine): + """智能海报引擎 V2 - 输出 Fabric.js JSON""" + + async def execute(self, params: dict) -> EngineResult: + # 1. AI 生成文案 + content = await self._generate_content(params) + + # 2. 选择布局和主题 + layout = content.get('suggested_layout') or self._recommend_layout(params) + theme = content.get('suggested_theme') or self._recommend_theme(params) + + # 3. 生成 Fabric JSON + fabric_json = self._generate_fabric_json(content, layout, theme, params) + + return EngineResult( + success=True, + data={ + 'fabric_json': fabric_json, + 'layout': layout, + 'theme': theme, + 'content': content + } + ) +``` + +### 前端 + +``` +components/ +├── PosterEditor/ +│ ├── index.tsx # 主组件 +│ ├── FabricCanvas.tsx # fabric.js 画布 +│ ├── LayerPanel.tsx # 图层面板 +│ ├── PropertyPanel.tsx # 属性面板 +│ └── ExportButton.tsx # 导出按钮 +``` + +#### 前端职责 + +1. **加载 Fabric JSON** - 解析 Python 返回的 JSON +2. **渲染画布** - fabric.js 渲染所有对象 +3. **用户编辑** - 支持移动、缩放、修改文字 +4. **导出图片** - 导出 PNG/JPG + +## 布局模板 + +### 5 种布局的 Fabric 结构 + +| 布局 | 结构 | +|-----|------| +| **hero_bottom** | 图片全屏 + 底部渐变 + 文字叠加 | +| **overlay_center** | 图片全屏 + 暗化遮罩 + 居中文字 | +| **overlay_bottom** | 图片上半 + 毛玻璃卡片底部 | +| **split_vertical** | 左侧渐变/图片 + 右侧文字 | +| **card_float** | 图片全屏 + 悬浮白色卡片 | + +### 布局模板文件 + +``` +poster_v2/templates/ +├── hero_bottom.json +├── overlay_center.json +├── overlay_bottom.json +├── split_vertical.json +└── card_float.json +``` + +## 主题配置 + +```python +THEMES = { + "sunset": { + "primary": "#594234", + "secondary": "#FFF5F0", + "accent": "#D4A574", + "text": "#FFFFFF", + "text_dark": "#333333", + "gradient": ["#FFE4D6", "#D4A574"] + }, + # ... 其他主题 +} +``` + +## API 设计 + +### 请求 + +```http +POST /api/v2/aigc/execute +Content-Type: application/json + +{ + "engine": "poster_smart_v2", + "params": { + "category": "民宿", + "name": "山舍云端民宿", + "description": "藏在莫干山的治愈系民宿", + "price": "458元/晚", + "image_url": "https://example.com/image.jpg" + } +} +``` + +### 响应 (双输出) + +```json +{ + "success": true, + "data": { + "preview_base64": "data:image/png;base64,...", + "fabric_json": { + "version": "1.0.0", + "canvas": { "width": 1080, "height": 1440 }, + "objects": [...] + }, + "layout": "hero_bottom", + "theme": "sunset", + "content": { + "title": "去了莫干山才知道...", + "subtitle": "...", + "highlights": [...], + "price": "¥458" + } + } +} +``` + +### 输出说明 + +| 字段 | 说明 | +|-----|------| +| `preview_base64` | **预览 PNG** - 无底图,使用主题渐变色背景,快速预览文案排版 | +| `fabric_json` | **Fabric JSON** - 完整的编辑数据,含图片占位,前端加载后可编辑 | +| `layout` | 推荐布局 | +| `theme` | 推荐主题 | +| `content` | AI 生成的文案内容 | + +## 实现步骤 + +### Phase 1: Python 端 (2-3天) + +1. [ ] 创建 `poster_smart_v2.py` 引擎 +2. [ ] 实现 5 种布局的 Fabric JSON 生成器 +3. [ ] 复用现有的 AI 文案生成逻辑 +4. [ ] 添加 API 路由 + +### Phase 2: 前端 (3-5天) + +1. [ ] 集成 fabric.js +2. [ ] 实现 FabricCanvas 组件 +3. [ ] 实现图层面板 +4. [ ] 实现属性编辑 +5. [ ] 实现导出功能 + +### Phase 3: 优化 (1-2天) + +1. [ ] 字体加载优化 +2. [ ] 图片懒加载 +3. [ ] 撤销/重做 +4. [ ] 模板保存 + +## 兼容性 + +- 保留 `poster_smart_v1` 引擎,支持服务端渲染 +- 新增 `poster_smart_v2` 引擎,支持 Fabric JSON 输出 +- 前端根据需求选择调用哪个引擎 + +## 优势 + +| 方面 | 收益 | +|-----|------| +| **性能** | 服务端不再处理图片,响应更快 | +| **可编辑** | 用户可自由调整文字、位置、颜色 | +| **灵活性** | 前端可扩展更多编辑功能 | +| **复用性** | Fabric JSON 可保存为模板复用 | + +## 风险与对策 + +| 风险 | 对策 | +|-----|------| +| 字体不一致 | 前端加载相同字体文件 | +| 跨域图片 | 配置 CORS 或使用代理 | +| 复杂效果 | 渐变、阴影用 fabric.js 内置功能 |