- 新增 PosterSmartEngine,AI 生成文案 + 海报渲染 - 5 种布局支持文本换行和自适应字体 - 修复按钮/标签颜色显示问题 - 优化渐变遮罩和内容区域计算 - Prompt 优化:标题格式为产品名+描述
473 lines
12 KiB
Markdown
473 lines
12 KiB
Markdown
# 海报系统设计思考
|
||
|
||
> 基于 `poster/templates/vibrant_template.py` 分析
|
||
> 创建日期: 2024-12-10
|
||
|
||
---
|
||
|
||
## 核心问题
|
||
|
||
**如何批量生成视觉美观的海报模板?**
|
||
|
||
技术实现(槽位、元素、渲染)相对简单,真正的挑战是:
|
||
- 什么样的布局是"好看"的?
|
||
- 如何系统化地产出大量"好看"的模板?
|
||
- 有没有可复用的设计规则?
|
||
|
||
---
|
||
|
||
## 一、美观的本质
|
||
|
||
### 1.1 设计的基本原则
|
||
|
||
| 原则 | 说明 | 海报中的体现 |
|
||
|-----|------|-------------|
|
||
| **对比** | 差异产生层次 | 大标题 vs 小说明 |
|
||
| **对齐** | 视觉秩序感 | 元素沿网格排列 |
|
||
| **重复** | 一致性、统一感 | 相同字体、颜色体系 |
|
||
| **亲密** | 相关元素靠近 | 价格和票种紧挨 |
|
||
| **留白** | 呼吸感、焦点突出 | 不塞满每个角落 |
|
||
| **层次** | 引导视觉流动 | 标题→副标题→详情 |
|
||
|
||
### 1.2 海报的视觉结构
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ │
|
||
│ 视觉焦点区 (Hero) │ ← 图片/主视觉
|
||
│ 占据 50-70% │
|
||
│ │
|
||
├─────────────────────────────────────┤
|
||
│ 核心信息区 (Core) │ ← 标题、价格
|
||
│ 占据 20-30% │
|
||
│ │
|
||
├─────────────────────────────────────┤
|
||
│ 辅助信息区 (Support) │ ← 详情、备注
|
||
│ 占据 10-20% │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
### 1.3 为什么有些海报好看?
|
||
|
||
**好看的共性**:
|
||
1. **焦点明确** - 一眼知道看什么
|
||
2. **层次清晰** - 信息有主次
|
||
3. **色彩和谐** - 不超过 3 种主色
|
||
4. **留白充足** - 不拥挤
|
||
5. **字体克制** - 不超过 2 种字体
|
||
|
||
**难看的共性**:
|
||
1. 信息堆砌,没有重点
|
||
2. 颜色杂乱,互相打架
|
||
3. 字体大小差异不够,层次模糊
|
||
4. 填满每一寸空间
|
||
|
||
---
|
||
|
||
## 二、批量生成美观模板的思路
|
||
|
||
### 2.1 思路对比
|
||
|
||
| 思路 | 描述 | 优点 | 缺点 |
|
||
|-----|------|------|------|
|
||
| **A: 人工设计** | 设计师逐个制作 | 质量高 | 成本高、数量有限 |
|
||
| **B: 参数变体** | 一个模板 + 参数变化 | 快速 | 同质化严重 |
|
||
| **C: 设计规则** | 定义规则,组合生成 | 可扩展 | 规则难以穷尽"美" |
|
||
| **D: AI 生成** | 用 AI 生成布局/配色 | 潜力大 | 质量不稳定 |
|
||
| **E: 混合方案** | 规则约束 + 设计资产库 | 平衡 | 需要前期投入 |
|
||
|
||
**建议: 方案 E - 设计规则 + 资产库**
|
||
|
||
### 2.2 设计资产库思路
|
||
|
||
```
|
||
美观模板 = 布局骨架 × 配色方案 × 字体组合 × 装饰元素
|
||
```
|
||
|
||
**布局骨架** (Layouts):
|
||
```yaml
|
||
layouts:
|
||
hero_bottom: # 大图在上,文字在下
|
||
image: [0, 0, 100%, 60%]
|
||
content: [0, 55%, 100%, 45%]
|
||
|
||
hero_left: # 大图在左,文字在右
|
||
image: [0, 0, 50%, 100%]
|
||
content: [50%, 0, 50%, 100%]
|
||
|
||
hero_center: # 文字叠加在图片中央
|
||
image: [0, 0, 100%, 100%]
|
||
content: [10%, 30%, 80%, 40%]
|
||
|
||
split_horizontal: # 上下分割
|
||
top: [0, 0, 100%, 50%]
|
||
bottom: [0, 50%, 100%, 50%]
|
||
|
||
card_style: # 卡片式,有边框和圆角
|
||
margin: 5%
|
||
border_radius: 20
|
||
shadow: true
|
||
```
|
||
|
||
**配色方案** (Color Schemes):
|
||
```yaml
|
||
color_schemes:
|
||
ocean:
|
||
primary: "#1a5f7a"
|
||
secondary: "#57c5b6"
|
||
accent: "#ffc107"
|
||
text: "#ffffff"
|
||
|
||
sunset:
|
||
primary: "#ff6b6b"
|
||
secondary: "#feca57"
|
||
accent: "#ffffff"
|
||
text: "#2d3436"
|
||
|
||
forest:
|
||
primary: "#2d5a27"
|
||
secondary: "#8bc34a"
|
||
accent: "#ffeb3b"
|
||
text: "#ffffff"
|
||
|
||
minimal:
|
||
primary: "#212121"
|
||
secondary: "#757575"
|
||
accent: "#ff5722"
|
||
text: "#ffffff"
|
||
|
||
pastel:
|
||
primary: "#a8d8ea"
|
||
secondary: "#aa96da"
|
||
accent: "#fcbad3"
|
||
text: "#2d3436"
|
||
```
|
||
|
||
**字体组合** (Font Pairs):
|
||
```yaml
|
||
font_pairs:
|
||
modern:
|
||
title: "阿里巴巴普惠体-Bold"
|
||
body: "思源黑体-Regular"
|
||
|
||
elegant:
|
||
title: "方正清刻本悦宋"
|
||
body: "思源宋体-Light"
|
||
|
||
playful:
|
||
title: "站酷快乐体"
|
||
body: "思源黑体-Regular"
|
||
|
||
business:
|
||
title: "兰亭黑-Heavy"
|
||
body: "兰亭黑-Light"
|
||
```
|
||
|
||
**装饰元素** (Decorations):
|
||
```yaml
|
||
decorations:
|
||
none: {}
|
||
|
||
line_divider:
|
||
type: line
|
||
position: below_title
|
||
width: 60%
|
||
|
||
gradient_overlay:
|
||
type: gradient
|
||
direction: bottom_up
|
||
opacity: 0.7
|
||
|
||
corner_badge:
|
||
type: badge
|
||
position: top_right
|
||
style: ribbon
|
||
|
||
bottom_wave:
|
||
type: shape
|
||
path: wave
|
||
position: bottom
|
||
```
|
||
|
||
### 2.3 组合生成
|
||
|
||
```
|
||
5 布局 × 10 配色 × 4 字体组合 × 5 装饰 = 1000 种组合
|
||
```
|
||
|
||
但不是所有组合都好看,需要:
|
||
|
||
1. **兼容性规则** - 哪些组合是合理的
|
||
2. **质量过滤** - 排除明显不好的组合
|
||
3. **人工精选** - 从中挑选最佳组合
|
||
|
||
### 2.4 兼容性矩阵
|
||
|
||
```yaml
|
||
compatibility:
|
||
# 布局 vs 配色
|
||
hero_bottom:
|
||
good_with: [ocean, sunset, forest] # 需要鲜明色彩
|
||
avoid: [minimal] # 太素会显空
|
||
|
||
hero_center:
|
||
good_with: [minimal, pastel] # 需要低对比度
|
||
avoid: [sunset] # 太强会干扰文字
|
||
|
||
# 字体 vs 场景
|
||
playful:
|
||
good_for: [亲子, 美食, 娱乐]
|
||
avoid_for: [商务, 地产, 金融]
|
||
|
||
elegant:
|
||
good_for: [酒店, 文化, 艺术]
|
||
avoid_for: [促销, 快消]
|
||
```
|
||
|
||
---
|
||
|
||
## 三、实用的模板生成策略
|
||
|
||
### 3.1 场景驱动
|
||
|
||
不要从"布局"出发,而是从**使用场景**出发:
|
||
|
||
```yaml
|
||
scenarios:
|
||
景点门票:
|
||
typical_content: [景点名, 价格, 票种, 有效期, 注意事项]
|
||
visual_style: 活力、明亮
|
||
recommended_layouts: [hero_bottom, hero_center]
|
||
recommended_colors: [ocean, sunset, forest]
|
||
|
||
酒店住宿:
|
||
typical_content: [酒店名, 房型, 价格, 设施, 地址]
|
||
visual_style: 优雅、高端
|
||
recommended_layouts: [hero_bottom, card_style]
|
||
recommended_colors: [minimal, pastel]
|
||
|
||
美食推荐:
|
||
typical_content: [店名, 招牌菜, 价格, 地址, 营业时间]
|
||
visual_style: 温暖、诱人
|
||
recommended_layouts: [hero_center, split_horizontal]
|
||
recommended_colors: [sunset, pastel]
|
||
|
||
促销活动:
|
||
typical_content: [活动名, 原价, 现价, 时间, 规则]
|
||
visual_style: 醒目、紧迫感
|
||
recommended_layouts: [hero_bottom]
|
||
recommended_colors: [sunset]
|
||
decorations: [corner_badge]
|
||
```
|
||
|
||
### 3.2 变体生成策略
|
||
|
||
从一个"基准模板"生成变体:
|
||
|
||
```
|
||
基准模板 (人工精调)
|
||
│
|
||
├─ 配色变体 (换色不换布局)
|
||
│ ├─ ocean 版
|
||
│ ├─ sunset 版
|
||
│ └─ forest 版
|
||
│
|
||
├─ 布局变体 (换布局不换风格)
|
||
│ ├─ 文字在下
|
||
│ ├─ 文字在右
|
||
│ └─ 文字叠加
|
||
│
|
||
└─ 密度变体 (同布局不同内容量)
|
||
├─ minimal 版 (只有标题+价格)
|
||
├─ standard 版 (标题+价格+列表)
|
||
└─ full 版 (所有信息)
|
||
```
|
||
|
||
### 3.3 设计约束(保底美观)
|
||
|
||
```yaml
|
||
constraints:
|
||
# 比例约束
|
||
title_to_body_ratio: [2, 4] # 标题是正文的 2-4 倍大
|
||
image_min_ratio: 0.4 # 图片至少占 40%
|
||
content_max_ratio: 0.5 # 文字最多占 50%
|
||
|
||
# 间距约束
|
||
min_margin: 5% # 最小边距
|
||
element_gap: 15-30px # 元素间距
|
||
|
||
# 颜色约束
|
||
max_colors: 3 # 最多 3 种主色
|
||
contrast_ratio: 4.5 # 文字对比度 (可读性)
|
||
|
||
# 字体约束
|
||
max_font_families: 2 # 最多 2 种字体
|
||
min_font_size: 14px # 最小字号
|
||
|
||
# 信息层级
|
||
levels:
|
||
- name: hero # 最突出
|
||
size: 60-150px
|
||
count: 1
|
||
- name: primary # 主要
|
||
size: 30-60px
|
||
count: 1-2
|
||
- name: secondary # 次要
|
||
size: 16-30px
|
||
count: 0-5
|
||
- name: tertiary # 辅助
|
||
size: 12-16px
|
||
count: 0-3
|
||
```
|
||
|
||
---
|
||
|
||
## 四、落地方案
|
||
|
||
### 4.1 短期:精选模板库
|
||
|
||
```
|
||
第一步:人工设计 10-20 个高质量基准模板
|
||
↓
|
||
第二步:每个模板生成 3-5 个配色变体
|
||
↓
|
||
第三步:形成 50-100 个可用模板
|
||
```
|
||
|
||
### 4.2 中期:规则化生成
|
||
|
||
```
|
||
第一步:抽象出布局骨架库 (5-10 种)
|
||
↓
|
||
第二步:抽象出配色方案库 (10-20 种)
|
||
↓
|
||
第三步:定义兼容性规则
|
||
↓
|
||
第四步:自动组合 + 人工筛选
|
||
```
|
||
|
||
### 4.3 长期:AI 辅助
|
||
|
||
```
|
||
第一步:收集优秀海报数据集
|
||
↓
|
||
第二步:训练/使用 AI 生成布局建议
|
||
↓
|
||
第三步:AI 配色推荐
|
||
↓
|
||
第四步:人工微调 + 质量把控
|
||
```
|
||
|
||
---
|
||
|
||
## 五、参考:业界做法
|
||
|
||
### Canva
|
||
- 10000+ 模板,人工设计为主
|
||
- 强调"替换即用",用户改图片和文字
|
||
- 模板按场景分类
|
||
|
||
### 稿定设计
|
||
- 模板 + 智能抠图
|
||
- 风格迁移(把 A 风格应用到 B 内容)
|
||
|
||
### 美图秀秀
|
||
- 模板 + AI 排版建议
|
||
- 根据图片内容推荐布局
|
||
|
||
### 关键启示
|
||
1. **模板数量很重要** - 用户需要选择
|
||
2. **场景分类很重要** - 快速找到合适的
|
||
3. **可定制性很重要** - 改颜色、改内容
|
||
4. **质量比数量重要** - 宁可少但精
|
||
|
||
---
|
||
|
||
## 六、下一步行动建议
|
||
|
||
### 优先级 1: 建立设计资产库
|
||
- [ ] 定义 5 种核心布局骨架
|
||
- [ ] 定义 10 种配色方案
|
||
- [ ] 定义 3-4 种字体组合
|
||
- [ ] 建立兼容性规则
|
||
|
||
### 优先级 2: 人工精调基准模板
|
||
- [ ] 针对"景点门票"场景,设计 3 个高质量模板
|
||
- [ ] 验证模板在不同内容下的表现
|
||
- [ ] 生成配色变体
|
||
|
||
### 优先级 3: 实现模板引擎
|
||
- [ ] 支持从 YAML 加载模板配置
|
||
- [ ] 支持动态切换配色
|
||
- [ ] 支持内容自适应
|
||
|
||
---
|
||
|
||
## 附录:VibrantTemplate 技术参考
|
||
|
||
以下是现有 `vibrant_template.py` 的技术细节,供重构参考。
|
||
|
||
### A.1 入口方法
|
||
|
||
```python
|
||
generate(images, content, theme_color, glass_intensity, num_variations, **kwargs)
|
||
```
|
||
|
||
**流程**:
|
||
1. 判断是否需要生成 Fabric.js JSON
|
||
2. 如果需要 → `_unified_render()` (PNG + JSON)
|
||
3. 否则 → `_generate_legacy()` (仅 PNG)
|
||
|
||
### A.2 核心功能模块
|
||
|
||
| 模块 | 方法 | 职责 |
|
||
|-----|------|------|
|
||
| **图片处理** | `resize_image` | 调整图片到目标尺寸 |
|
||
| **渐变检测** | `_detect_gradient_start_position` | 智能检测毛玻璃起始位置 |
|
||
| **颜色提取** | `_extract_glass_colors_from_image` | 从图片提取毛玻璃颜色 |
|
||
| **毛玻璃效果** | `_create_frosted_glass_overlay` | 创建渐变半透明覆盖层 |
|
||
| **布局计算** | `_calculate_content_margins` | 计算内容区域边距 |
|
||
| **字体自适应** | `_calculate_optimal_font_size_enhanced` | 二分查找最佳字体大小 |
|
||
| **文字渲染** | `_render_texts` | 渲染所有文本元素 |
|
||
| **PSD 生成** | `generate_layered_psd` | 生成分层 PSD 文件 |
|
||
|
||
### A.3 内容数据结构
|
||
|
||
```python
|
||
content = {
|
||
"title": "正佳极地海洋世界", # 必选
|
||
"slogan": "都说海洋馆是约会圣地!", # 重要
|
||
"price": "199", # 必选
|
||
"ticket_type": "夜场票", # 重要
|
||
"content_button": "套餐内容",
|
||
"content_items": ["项目1", "项目2"], # 重要
|
||
"remarks": ["备注1", "备注2"], # 可选
|
||
"tag": "#520特惠", # 可选
|
||
"pagination": "1/3" # 可选
|
||
}
|
||
```
|
||
|
||
### A.4 问题清单
|
||
|
||
| 问题 | 说明 |
|
||
|-----|------|
|
||
| 文件过大 | 1757 行 |
|
||
| 重复代码 | `_create_text_only_layer` 定义两次 |
|
||
| 硬编码参数 | 字体路径、位置像素值 |
|
||
| 职责混杂 | 布局、渲染、特效混在一起 |
|
||
|
||
### A.5 渲染流程
|
||
|
||
```
|
||
generate() → _generate_legacy()
|
||
├─ resize_image()
|
||
├─ _detect_gradient_start_position()
|
||
├─ _create_composite_image()
|
||
│ └─ _create_frosted_glass_overlay()
|
||
└─ _render_texts()
|
||
├─ _render_title_subtitle()
|
||
├─ _render_left_column()
|
||
├─ _render_right_column()
|
||
└─ _render_footer()
|
||
```
|