- 新增 PosterSmartEngine,AI 生成文案 + 海报渲染 - 5 种布局支持文本换行和自适应字体 - 修复按钮/标签颜色显示问题 - 优化渐变遮罩和内容区域计算 - Prompt 优化:标题格式为产品名+描述
12 KiB
12 KiB
海报系统设计思考
基于
poster/templates/vibrant_template.py分析
创建日期: 2024-12-10
核心问题
如何批量生成视觉美观的海报模板?
技术实现(槽位、元素、渲染)相对简单,真正的挑战是:
- 什么样的布局是"好看"的?
- 如何系统化地产出大量"好看"的模板?
- 有没有可复用的设计规则?
一、美观的本质
1.1 设计的基本原则
| 原则 | 说明 | 海报中的体现 |
|---|---|---|
| 对比 | 差异产生层次 | 大标题 vs 小说明 |
| 对齐 | 视觉秩序感 | 元素沿网格排列 |
| 重复 | 一致性、统一感 | 相同字体、颜色体系 |
| 亲密 | 相关元素靠近 | 价格和票种紧挨 |
| 留白 | 呼吸感、焦点突出 | 不塞满每个角落 |
| 层次 | 引导视觉流动 | 标题→副标题→详情 |
1.2 海报的视觉结构
┌─────────────────────────────────────┐
│ │
│ 视觉焦点区 (Hero) │ ← 图片/主视觉
│ 占据 50-70% │
│ │
├─────────────────────────────────────┤
│ 核心信息区 (Core) │ ← 标题、价格
│ 占据 20-30% │
│ │
├─────────────────────────────────────┤
│ 辅助信息区 (Support) │ ← 详情、备注
│ 占据 10-20% │
└─────────────────────────────────────┘
1.3 为什么有些海报好看?
好看的共性:
- 焦点明确 - 一眼知道看什么
- 层次清晰 - 信息有主次
- 色彩和谐 - 不超过 3 种主色
- 留白充足 - 不拥挤
- 字体克制 - 不超过 2 种字体
难看的共性:
- 信息堆砌,没有重点
- 颜色杂乱,互相打架
- 字体大小差异不够,层次模糊
- 填满每一寸空间
二、批量生成美观模板的思路
2.1 思路对比
| 思路 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| A: 人工设计 | 设计师逐个制作 | 质量高 | 成本高、数量有限 |
| B: 参数变体 | 一个模板 + 参数变化 | 快速 | 同质化严重 |
| C: 设计规则 | 定义规则,组合生成 | 可扩展 | 规则难以穷尽"美" |
| D: AI 生成 | 用 AI 生成布局/配色 | 潜力大 | 质量不稳定 |
| E: 混合方案 | 规则约束 + 设计资产库 | 平衡 | 需要前期投入 |
建议: 方案 E - 设计规则 + 资产库
2.2 设计资产库思路
美观模板 = 布局骨架 × 配色方案 × 字体组合 × 装饰元素
布局骨架 (Layouts):
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):
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):
font_pairs:
modern:
title: "阿里巴巴普惠体-Bold"
body: "思源黑体-Regular"
elegant:
title: "方正清刻本悦宋"
body: "思源宋体-Light"
playful:
title: "站酷快乐体"
body: "思源黑体-Regular"
business:
title: "兰亭黑-Heavy"
body: "兰亭黑-Light"
装饰元素 (Decorations):
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 种组合
但不是所有组合都好看,需要:
- 兼容性规则 - 哪些组合是合理的
- 质量过滤 - 排除明显不好的组合
- 人工精选 - 从中挑选最佳组合
2.4 兼容性矩阵
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 场景驱动
不要从"布局"出发,而是从使用场景出发:
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 设计约束(保底美观)
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: 建立设计资产库
- 定义 5 种核心布局骨架
- 定义 10 种配色方案
- 定义 3-4 种字体组合
- 建立兼容性规则
优先级 2: 人工精调基准模板
- 针对"景点门票"场景,设计 3 个高质量模板
- 验证模板在不同内容下的表现
- 生成配色变体
优先级 3: 实现模板引擎
- 支持从 YAML 加载模板配置
- 支持动态切换配色
- 支持内容自适应
附录:VibrantTemplate 技术参考
以下是现有 vibrant_template.py 的技术细节,供重构参考。
A.1 入口方法
generate(images, content, theme_color, glass_intensity, num_variations, **kwargs)
流程:
- 判断是否需要生成 Fabric.js JSON
- 如果需要 →
_unified_render()(PNG + JSON) - 否则 →
_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 内容数据结构
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()