> ⚠️ 本技能是严格操作手册,不是设计参考。必须按流程逐步执行,不可跳步。
必须输出以下设计规范表,后续所有步骤依据此表:
设计规范:
- Rendering: [从下表选一个]
- Palette: [从下表选一个]
- 是否Dark Mode: [是/否]
- 每页布局规划:
页1: [布局类型] - [内容摘要]
页2: [布局类型] - [内容摘要]
...
Rendering(视觉风格)选择表:
| 场景 | Rendering | AI生图Prompt关键词 |
|---|---|---|
| ------ | ----------- | ------------------- |
| 企业/咨询/汇报 | corporate-photo | professional corporate, editorial photography, clean environment, warm natural lighting |
| 旅行/品牌故事 | warm-scene | warm cinematic scene, golden hour, editorial travel photography, atmospheric mood |
| 科技/SaaS/AI | blueprint | technical blueprint, clean technical illustration, precise lines |
| 科技/SaaS/AI | 3d-isometric | isometric 3D illustration, clean geometric shapes, soft shadows |
| 科技Pitch/Dark | dark-neon | low-key lighting, dramatic shadows, neon accent glow, dark cinematic |
| 教育/培训 | sketch-notes | hand-drawn sketch, notebook aesthetic, doodle elements, warm paper texture |
| 文化/节庆 | paper-cut | traditional paper-cut art, layered silhouettes, cultural motifs |
| 文化/节庆 | vintage-poster | retro vintage poster, aged paper texture, classic typography |
| 品牌故事/年报 | editorial | magazine editorial, sophisticated composition, cinematic lighting |
| 投资路演/Keynote | typography-hero | minimal background, subtle texture, clean negative space |
| 怀旧品牌/创意 | retrofuturism | retro-futuristic, chrome metallic finish, vintage color palette |
Palette(色彩方案)选择表:
| 主题方向 | 推荐Palette | 主色系 | 强调色 | 背景基调 |
|---|---|---|---|---|
| --------- | ------------ | -------- | -------- | --------- |
| 科技/AI/电子/制造 | dark-mode | 深炭灰#12131A | 霓虹青#00E5CC | #12131A |
| 金融/咨询/汇报 | cool-corporate | 深海军蓝#1B3A5C | 铜金#C8956C | 浅蓝灰白#F2F4F7 |
| 旅行/草原/户外/景区 | nature-organic | 深林绿#3D5A40 | 琥珀蜜#C8956C | 暖米白#F7F3EC |
| 旅行(暖调)/美食 | sunset-gradient | 暮色玫瑰#D4727A | 暮紫#9B6B9E | 暖白#FFF5EE |
| 奢侈/时尚/品牌 | jewel-tone | 宝石墨绿#1A3C34 | 鎏金#D4AF37 | 暖黑#0F0F0F |
| 医疗/健康/美业 | restorative-teal | 治愈青#2A9D8F | 深紫#6B4C7A | 霜白#F4F1EC |
| 文化/节庆/非遗 | warm-earth | 赭石#8A5A3A | 旧金#C8A860 | 米色#F5F0E0 |
| 教育/培训 | macaron | 灰蓝#7A8AAA | 暖杏#E8A87A | 柔白#F8F6F2 |
| 极简/方法论 | mono-ink | 墨黑蓝#1A1B2E | 朱砂橘#E85D3A | 近白#FAFAFA |
| 品牌单色 | monochromatic | 品牌色 | 品牌色高亮 | 近白/深炭灰 |
选定Palette后,必须将8色角色全部定义到Python字典C中。整份PPT只使用C中的颜色。
以下是各Palette的完整8色定义,直接复制使用:
dark-modeC = {
'primary': '#12131A', # 深炭灰(主色/背景)
'secondary': '#1E2030', # 深灰(卡片)
'accent': '#00E5CC', # 霓虹青(强调)
'accent2': '#4D8DFF', # 电蓝(辅助强调)
'accent3': '#00FFB2', # 薄荷绿(辅助强调)
'bg': '#12131A', # 背景
'text': '#E8E8EC', # 白色文字
'text_light': '#A0A0B0', # 浅灰文字
'text_dim': '#606070', # 暗灰文字
'overlay': '#0A0B10', # 极深遮罩
'white': '#FFFFFF',
}
nature-organicC = {
'primary': '#3D5A40', # 深林绿
'secondary': '#7A9E7E', # 苔藓绿
'accent': '#C8956C', # 琥珀蜜
'accent2': '#DDB892', # 浅琥珀
'bg': '#F7F3EC', # 暖米白
'text': '#2D3A2E', # 深绿文字
'text_light': '#8A9B8C', # 浅绿文字
'overlay': '#1A2620', # 深墨绿遮罩
'white': '#FFFFFF',
'cream': '#EDE5D8', # 暖米
}
cool-corporateC = {
'primary': '#1B3A5C', # 深海军蓝
'secondary': '#2E5A8A', # 中蓝
'accent': '#C8956C', # 铜金
'accent2': '#D4A574', # 浅铜金
'bg': '#F2F4F7', # 浅蓝灰白
'text': '#1E2D3D', # 深灰蓝
'text_light': '#7A8A9A', # 灰蓝
'overlay': '#0D1B2A', # 极深蓝
'white': '#FFFFFF',
}
sunset-gradientC = {
'primary': '#D4727A', # 暮色玫瑰
'secondary': '#E8985A', # 暮橘
'accent': '#9B6B9E', # 暮紫
'accent2': '#C0808A', # 浅玫瑰
'bg': '#FFF5EE', # 暖白
'text': '#3A2E35', # 深紫棕
'text_light': '#9A8A8E', # 灰玫瑰
'overlay': '#1A1520', # 极深紫
'white': '#FFFFFF',
}
jewel-toneC = {
'primary': '#1A3C34', # 宝石墨绿
'secondary': '#5A1A2A', # 深酒红
'accent': '#D4AF37', # 鎏金
'accent2': '#E8C860', # 浅金
'bg': '#0F0F0F', # 暖黑
'text': '#F0EDE8', # 暖白
'text_light': '#9A9590', # 暖灰
'overlay': '#0A0A0A', # 极深黑
'white': '#FFFFFF',
}
restorative-tealC = {
'primary': '#2A9D8F', # 治愈青
'secondary': '#5C7A6E', # 大地绿
'accent': '#6B4C7A', # 深紫
'accent2': '#8A6A9A', # 浅紫
'bg': '#F4F1EC', # 霜白
'text': '#2D3A3A', # 深灰绿
'text_light': '#8A9A95', # 浅绿灰
'overlay': '#1A2A28', # 深青灰
'white': '#FFFFFF',
}
warm-earthC = {
'primary': '#8A5A3A', # 赭石
'secondary': '#6A4A3A', # 深赭
'accent': '#C8A860', # 旧金
'accent2': '#D4B870', # 浅旧金
'bg': '#F5F0E0', # 米色
'text': '#3A2A1A', # 深褐
'text_light': '#8A7A6A', # 灰褐
'overlay': '#1A1510', # 极深褐
'white': '#FFFFFF',
}
macaronC = {
'primary': '#7A8AAA', # 灰蓝
'secondary': '#8A7AAA', # 灰紫
'accent': '#E8A87A', # 暖杏
'accent2': '#F0C0A0', # 浅杏
'bg': '#F8F6F2', # 柔白
'text': '#3A3A4A', # 深灰紫
'text_light': '#9A9AAA', # 灰
'overlay': '#1A1A2A', # 极深紫灰
'white': '#FFFFFF',
}
mono-inkC = {
'primary': '#1A1B2E', # 墨黑蓝
'secondary': '#3A3B4E', # 灰蓝
'accent': '#E85D3A', # 朱砂橘
'accent2': '#F07050', # 浅朱砂
'bg': '#FAFAFA', # 近白
'text': '#1A1B2E', # 墨黑蓝
'text_light': '#8A8A9A', # 灰
'overlay': '#0D0E1A', # 极深墨
'white': '#FFFFFF',
}
monochromatic(需要品牌色,用此模板替换)C = {
'primary': '{品牌色}',
'secondary': '{品牌色降亮度20%}',
'accent': '{品牌色提饱和度}',
'accent2': '{品牌色浅调}',
'bg': '#FAFAFA', # 近白(暗版用 #12131A)
'text': '#1A1B2E', # 暗版用 #E8E8EC
'text_light': '#8A8A9A',
'overlay': '#0D0E1A',
'white': '#FFFFFF',
}
这是最容易出问题的步骤。必须严格执行。
根据Step 1的布局规划,列出需要配图的页面:
工具名称:image_generate
调用方式(每张图单独调用):
image_generate(
prompt="你的图片描述",
count=1,
file_prefix="ppt_页码_用途" # 如 ppt_cover, ppt_p2_scene
)
Prompt 构成公式(必须遵守):
[场景描述], [光线/氛围], [摄影风格], muted color grading, desaturated, editorial quality, 16:9 aspect ratio
按Rendering风格加前缀:
dark-neon → 加 low-key lighting, dramatic shadows, moody atmosphere, neon accent glowwarm-scene → 加 golden hour lighting, warm cinematic atmospherecorporate-photo → 加 professional corporate photography, clean environment, warm natural lightingnature-organic → 加 natural outdoor photography, soft daylight生图数量参考:
生图完成后,记录返回的文件路径。在Python脚本中用这些路径。
图片路径示例:
IMG_DIR = '/app/data/所有对话/主对话/imgs/生成目录'
# 或相对路径:
IMG_DIR = './images'
#!/usr/bin/env python3
"""[PPT标题] — [Rendering] Rendering + [Palette] Palette"""
import sys, os
# 导入工具函数 — 这行必须保留,路径不要改
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scripts'))
from ppt_builder import *
# ====== 配色字典(从Step 2复制) ======
C = {
# ... 从Step 2复制的完整配色字典
}
# ====== 常量 ======
SLIDE_W = Inches(13.333)
SLIDE_H = Inches(7.5)
IMG_DIR = '[图片目录路径]' # Step 3中记录的路径
# ====== 创建演示文稿 ======
prs = Presentation()
prs.slide_width = SLIDE_W
prs.slide_height = SLIDE_H
slide = prs.slides.add_slide(prs.slide_layouts[6])
# 底层:全出血图片
add_image(slide, os.path.join(IMG_DIR, 'cover.jpg'), 0, 0, SLIDE_W, SLIDE_H)
# 中层:底部渐变遮罩(关键!不是简单色块)
add_gradient_rect(slide, 0, Inches(2.0), SLIDE_W, Inches(5.5),
C['overlay'], C['bg'], opacity1=0.88, opacity2=0.0, angle=5400000)
# 叠加第二层遮罩增加深度
add_gradient_rect(slide, 0, Inches(5.5), SLIDE_W, Inches(2.0),
C['overlay'], C['overlay'], opacity1=0.65, opacity2=0.0, angle=5400000)
# 装饰线(强调色!)
add_accent_line(slide, Inches(1.0), Inches(4.2), Inches(1.2), C['accent'], Pt(3))
# 主标题
add_text_box(slide, Inches(1.0), Inches(4.5), Inches(9), Inches(1.2),
'标题文字', font_size=56, color=C['text'], bold=True)
# 副标题
add_text_box(slide, Inches(1.0), Inches(5.6), Inches(9), Inches(0.5),
'副标题文字', font_size=20, color=C['accent'])
slide = prs.slides.add_slide(prs.slide_layouts[6])
# 背景
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['bg'])
# 右半:配图
add_image(slide, os.path.join(IMG_DIR, 'scene.jpg'),
Inches(6.8), 0, Inches(6.533), SLIDE_H)
# 图片侧渐变衔接(关键!柔和过渡到文字区)
add_gradient_rect(slide, Inches(6.8), 0, Inches(3.0), SLIDE_H,
C['bg'], C['bg'], opacity1=0.95, opacity2=0.0, angle=0)
# 左侧竖装饰线
add_solid_rect(slide, Inches(0.8), Inches(0.8), Pt(3), Inches(5.8), C['accent'])
# 章节编号
add_text_box(slide, Inches(1.2), Inches(0.8), Inches(1.5), Inches(0.5),
'01', font_size=36, color=C['accent'], bold=True)
# 标题
add_text_box(slide, Inches(1.2), Inches(1.5), Inches(5.0), Inches(0.7),
'页面标题', font_size=36, color=C['text'], bold=True)
# 装饰线
add_accent_line(slide, Inches(1.2), Inches(2.2), Inches(0.8), C['accent'], Pt(2))
# 正文内容
add_multiline_text(slide, Inches(1.2), Inches(2.6), Inches(5.0), Inches(3.5),
['第一段要点', '第二段要点', '第三段要点'],
font_size=16, color=C['text_light'])
> 💡 左图右文时:图片放左侧(x=0, width=6.5),文字放右侧(x=7.0),渐变方向angle=0改为从右向左
slide = prs.slides.add_slide(prs.slide_layouts[6])
# 背景
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['bg']) # Dark Mode用 C['primary']
# 页面标题
add_text_box(slide, Inches(0.8), Inches(0.5), Inches(5), Inches(0.5),
'分类标题', font_size=14, color=C['text_dim'])
add_accent_line(slide, Inches(0.8), Inches(1.0), Inches(0.8), C['accent'], Pt(2))
add_text_box(slide, Inches(0.8), Inches(1.15), Inches(6), Inches(0.7),
'页面大标题', font_size=36, color=C['text'], bold=True)
# Bento卡片 — 大hero模块
add_bento_card(slide, Inches(0.8), Inches(2.2), Inches(5.8), Inches(2.5),
title='指标名称', metric='72.5', unit='B',
annotation='注释说明',
bg_color=C['secondary'], metric_color=C['accent'])
# Bento卡片 — 中模块(2个并排)
add_bento_card(slide, Inches(6.9), Inches(2.2), Inches(5.6), Inches(1.15),
title='指标2', metric='38.2', unit='%',
annotation='注释',
bg_color=C['secondary'], metric_color=C['accent2'])
add_bento_card(slide, Inches(6.9), Inches(3.55), Inches(5.6), Inches(1.15),
title='指标3', metric='12.3', unit='%',
annotation='注释',
bg_color=C['secondary'], metric_color=C['accent3'] if 'accent3' in C else C['accent'])
# Bento卡片 — 底部小模块(3个并排)
add_bento_card(slide, Inches(0.8), Inches(5.0), Inches(3.8), Inches(1.8),
title='指标4', metric='68', unit='%',
annotation='注释',
bg_color=C['secondary'], metric_color=C['accent'])
add_bento_card(slide, Inches(4.85), Inches(5.0), Inches(3.8), Inches(1.8),
title='指标5', metric='50K+', unit='',
annotation='注释',
bg_color=C['secondary'], metric_color=C['accent2'])
add_bento_card(slide, Inches(8.9), Inches(5.0), Inches(3.6), Inches(1.8),
title='指标6', metric='4.2B', unit='片',
annotation='注释',
bg_color=C['secondary'], metric_color=C['accent3'] if 'accent3' in C else C['accent'])
slide = prs.slides.add_slide(prs.slide_layouts[6])
# 纯色背景
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['bg'])
# 可选:微弱装饰光晕(Dark Mode特别有效)
add_gradient_rect(slide, Inches(8.0), 0, Inches(5.3), Inches(4.0),
C['secondary'], C['bg'], opacity1=0.3, opacity2=0.0, angle=5400000)
# Hero大字(标题本身就是视觉元素)
add_hero_text(slide, Inches(1.0), Inches(1.8), Inches(11), Inches(3.0),
headline='核心观点第一行',
headline_color=C['text'], headline_size=80)
add_hero_text(slide, Inches(1.0), Inches(3.2), Inches(11), Inches(2.0),
headline='核心观点第二行',
headline_color=C['accent'], headline_size=80)
# 支撑文字
add_text_box(slide, Inches(1.0), Inches(5.2), Inches(8), Inches(0.5),
'支撑说明文字,一句话解释核心观点的背景和意义',
font_size=18, color=C['text_light'])
# 装饰线
add_accent_line(slide, Inches(1.0), Inches(5.8), Inches(2.0), C['accent'], Pt(2))
slide = prs.slides.add_slide(prs.slide_layouts[6])
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['bg'])
# 拉引样式
add_pull_quote(slide, Inches(1.5), Inches(1.2), Inches(10.0), Inches(4.0),
quote_text='引述内容,可以是品牌Slogan、客户评价、核心理念',
attribution='出处/作者',
accent_color=C['accent'], quote_size=28,
font_name='SimSun') # 宋体营造编辑感
# 底部补充文字
add_text_box(slide, Inches(1.5), Inches(5.5), Inches(8), Inches(0.5),
'补充说明文字', font_size=16, color=C['text_light'])
slide = prs.slides.add_slide(prs.slide_layouts[6])
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['bg'])
# 左1/3:大数字
add_data_card(slide, Inches(0.8), Inches(1.5), Inches(4.0), Inches(3.5),
metric='72.5', unit='B',
so_what='核心洞察:这个数字意味着什么',
source='数据来源: IPC, 2024',
metric_color=C['accent'],
bg_color=C['secondary'])
# 右2/3:补充说明
add_text_box(slide, Inches(5.5), Inches(1.5), Inches(6.5), Inches(0.5),
'背景说明', font_size=14, color=C['text_light'])
add_multiline_text(slide, Inches(5.5), Inches(2.2), Inches(6.5), Inches(3.0),
['要点1', '要点2', '要点3'],
font_size=16, color=C['text'])
slide = prs.slides.add_slide(prs.slide_layouts[6])
add_solid_rect(slide, 0, 0, SLIDE_W, SLIDE_H, C['primary'])
# 章节编号+标题
add_text_box(slide, Inches(1.2), Inches(0.8), Inches(1.5), Inches(0.5),
'01', font_size=36, color=C['accent'], bold=True)
add_text_box(slide, Inches(1.2), Inches(1.5), Inches(5.0), Inches(0.7),
'页面标题', font_size=36, color=C['text'], bold=True)
add_accent_line(slide, Inches(1.2), Inches(2.2), Inches(0.8), C['accent'], Pt(2))
# 步骤卡片列表
steps = [
('步骤1', '步骤1的详细描述'),
('步骤2', '步骤2的详细描述'),
('步骤3', '步骤3的详细描述'),
('步骤4', '步骤4的详细描述'),
]
for i, (title, desc) in enumerate(steps):
y = Inches(2.6) + i * Inches(1.15)
add_rounded_rect(slide, Inches(1.2), y, Inches(5.0), Inches(0.95), C['secondary'])
add_text_box(slide, Inches(2.1), y + Inches(0.12), Inches(3.8), Inches(0.35),
title, font_size=16, color=C['text'], bold=True)
add_text_box(slide, Inches(2.1), y + Inches(0.45), Inches(3.8), Inches(0.45),
desc, font_size=11, color=C['text_light'])
# ====== 保存 ======
OUTPUT = '[输出文件路径].pptx'
prs.save(OUTPUT)
# ====== 自检 ======
print(f'Saved: {OUTPUT}')
print(f'Pages: {len(prs.slides)}')
for i, s in enumerate(prs.slides):
shapes = s.shapes
img_count = sum(1 for sh in shapes if sh.shape_type == 13) # 13 = picture
print(f' Page {i+1}: {len(shapes)} shapes, {img_count} images')
执行脚本生成PPTX文件后,检查:
告知用户PPTX文件路径,说明"文字可直接编辑,配图可右键替换"。
| 函数 | 用途 | 关键参数 |
|---|---|---|
| ------ | ------ | --------- |
hex2rgb(h) | HEX→RGBColor | h: '#FF0000' |
add_gradient_rect(slide, left, top, width, height, color1, color2, opacity1, opacity2, angle) | 渐变矩形(遮罩/氛围) | angle: 5400000=底→顶, 0=左→右 |
add_solid_rect(slide, left, top, width, height, color, opacity) | 纯色矩形(背景/装饰线) | opacity: 0.0~1.0 |
add_rounded_rect(slide, left, top, width, height, color, opacity, corner_radius) | 圆角矩形(卡片) | 默认圆角0.15英寸 |
add_glassmorphism_rect(slide, left, top, width, height, fill_color, fill_opacity, border_color, border_opacity) | 毛玻璃卡片 | 每份PPT仅1-2处 |
add_accent_line(slide, left, top, width, color, height) | 装饰线 | height默认Pt(2) |
add_text_box(slide, left, top, width, height, text, font_size, color, bold, alignment, font_name) | 文本框 | font_name默认Microsoft YaHei |
add_multiline_text(slide, left, top, width, height, lines, font_size, color) | 多行文本 | lines为字符串列表 |
add_image(slide, img_path, left, top, width, height) | 图片 | 全出血: 0,0,SLIDE_W,SLIDE_H |
| 函数 | 用途 | 关键参数 |
|---|---|---|
| ------ | ------ | --------- |
add_bento_card(slide, left, top, width, height, title, metric, unit, annotation, bg_color, metric_color) | Bento Grid卡片 | metric大数字(36pt)+注释(11pt) |
add_data_card(slide, left, top, width, height, metric, unit, so_what, source, metric_color, bg_color) | 数据洞察卡片 | metric大数字(48pt)+So What(14pt) |
add_hero_text(slide, left, top, width, height, headline, subtitle, headline_color, headline_size) | Typography Hero | 默认80pt |
add_pull_quote(slide, left, top, width, height, quote_text, attribution, accent_color, quote_size, font_name) | Editorial拉引 | 默认宋体,大引号装饰 |
| 错误 | 正确做法 |
|---|---|
| ------ | --------- |
| 全出血页没有遮罩直接放文字 | 必须加 add_gradient_rect 遮罩层 |
| 遮罩用纯黑半透明色块 | 用 C['overlay'](不是纯黑)+ 渐变(不是单色) |
| 装饰线用主色/随机色 | 只用 C['accent'] |
| 每页都是左文右图 | 5页至少3种布局 |
| 配图用卡通/插画风格 | 默认真实摄影,除非用户指定 |
| Bento Grid每模块一样大 | 必须有大小差异(1大hero + 2-3中/小) |
| 正文12pt、标题24pt | 正文≥16pt,标题≥36pt |
| 配色随机拼凑 | 整份PPT只用一个Palette的C字典 |
| Glassmorphism到处用 | 每份PPT仅1-2处 |
| 跳过生图步骤 | 全出血/图文分栏页必须有图,失败则重试 |
5页PPT的典型节奏(至少3种布局):
科技/商务场景:
旅行/自然/文化场景:
数据/咨询场景:
python-pptx >= 0.6.21lxml >= 4.9.0安装:pip install python-pptx lxml
共 2 个版本