Skill: ameylover/ppt-pandora (version 1.1.0)

--- name: ppt-pandora description: > PPT完整制作流程：从素材收集、大纲规划，到图片搜索/裁剪/插入、文字排版调整（字体大小/行间距/位置）、 表格处理、整体视觉评估，直到最终验证。支持红白风格等专业PPT的全流程制作。 metadata: {"openclaw": {"emoji": "📊", "os": ["darwin", "linux"]}} --- # PPT完整制作流程 ## 一、素材收集与规划 ### 1.1 内容来源优先级 1. **权威官方报道**（gov.cn、news.cn、people.com.cn）— 政策、数据、事件 2. **证券研究所报告** — 产业架构图、行业数据图表（极其权威专业） 3. **Pexels免费图库** — 通用场景照片 4. **AI生成图片** — 无版权风险，但质量不稳定 ### 1.2 贾老师找图法（内容→来源→关联→配图） 1. 看PPT页面的**核心主题和引用内容**（政策引领？技术趋势？行业案例？） 2. 搜索**引用的原话**，找到权威官方报道 3. 从报道里找**关联事件**（上下文提到的会议/政策/人物/数据） 4. 用关联事件去搜对应的图片 **为什么有效**：图片和内容有逻辑关联，不是随便配的免费图。 **示例**： - P3 讲"政策引领+习主席指示" → 搜习主席原话 → 找到发改委文章 → 文章提到"二十届三中全会" → 搜该会议照片 - P4 讲"十五五规划+人工智能+" → 搜十五五报道 → gov.cn文章有李强主持编制会议照片 - P6 讲"中国AI产业" → 搜"AI产业层级架构" → 华西证券研究所报告图片 ### 1.3 特殊图片渠道 - **gov.cn图片路径**：`./W0xxxxxxxxxx_ORIGIN.JPG`（拼接完整URL） - **人民网图片路径**：`/NMediaFile/xxxxx/MAINxxxxxxxx.jpg` - **证券研究所图片**：搜索"XX证券 AI产业"或"XX证券 行业图谱" --- ## 二、图片裁剪与适配 ### 2.1 核心原则 1. **绝不拉伸**，保持原始宽高比 2. 裁剪时**保留重要内容**（人脸、文字不能切掉） 3. 从**不重要部分**裁切（下半身、留白、背景） 4. 卡片圆弧角 → **必须留边距**（≥0.15英寸） ### 2.2 裁剪策略速查表 | 场景 | 策略 | |------|------| | 竖图→横卡片 | 裁掉不重要部分（下半身/背景），保留上半部分，居中放置 | | 文字在底部 | 裁上方留白，让文字靠上 | | 人脸照片 | 用image工具定位脸坐标，以脸为中心裁剪 | | 横图→横卡片 | 从上下等比裁切，保持居中 | | 比例接近但不匹配 | 微调裁切量，尽量保留主要内容 | | 图片比预留区域小 | 按比例缩放后居中放置，四周留白，绝不拉伸 | ### 2.3 边距规范 | 边距大小 | 适用场景 | |----------|----------| | 0.15英寸 | 最小值，刚好避免直角碰圆弧 | | 0.3英寸 | 通用推荐值 | | 0.5英寸 | 需要明显留白时 | ### 2.4 Python代码示例 ```python from pptx.util import Inches # 图片在卡片区域内带边距 card_left, card_top, card_w, card_h = 0.8, 1.8, 5.0, 2.5 margin = 0.15 img_left = card_left + margin img_top = card_top + margin img_w = card_w - 2 * margin img_h = img_w / image_aspect_ratio # 等比计算高度 # 居中在卡片区域内 img_top = card_top + (card_h - img_h) / 2 slide.shapes.add_picture(img_path, Inches(img_left), Inches(img_top), Inches(img_w), Inches(img_h)) ``` --- ## 三、文字排版调整 ### 3.1 核心三要素：字体大小 + 行间距 + 文本框高度 **三者必须配合调整**，只改一个参数往往视觉效果不好。 | 场景 | 字体大小 | 行间距 | 文本框高度 | |------|----------|--------|------------| | 正文段落（填满区域） | 18-20pt | 1.5-2.0x | 匹配内容 | | 数据卡片标签 | 16pt | 1.0x | 自适应 | | 数据卡片数值 | 28pt | 1.0x | 自适应 | | 数据卡片单位 | 14pt | 1.0x | 自适应 | | 标题 | 24-32pt | 1.0x | 自适应 | ### 3.2 视觉评估原则 **不是参数万能，是根据实际情况定的。** 判断标准： - 文字是否填满区域（不空不挤） - 行间距是否让文字呼吸（1.5-2.0x适合段落） - 字体大小是否与区域面积匹配 - 整体是否上下居中 ### 3.3 主副标题合并 ```python # 用破折号连接，解决右侧太空问题 shape.text_frame.paragraphs[0].text = f'{main_title}——{subtitle}' # 删除旧的副标题shape sub_shape._element.getparent().remove(sub_shape._element) ``` ### 3.4 文字垂直居中（XML方式） ```python from pptx.oxml.ns import qn sp = shape._element for child in sp: tag = child.tag.split('}')[-1] if '}' in child.tag else child.tag if tag == 'txBody': for sub in child: subtag = sub.tag.split('}')[-1] if '}' in sub.tag else sub.tag if subtag == 'bodyPr': sub.set('anchor', 'ctr') # 垂直居中 ``` ### 3.5 python-pptx 添加新段落 ```python # ❌ 错误：paragraphs[3] 访问不存在的段落不会自动创建 # ✅ 正确：手动创建XML paragraph元素 from pptx.oxml.ns import qn txBody = shape.text_frame._txBody new_p = txBody.makeelement(qn('a:p'), {}) r = new_p.makeelement(qn('a:r'), {}) rPr = r.makeelement(qn('a:rPr'), {'lang': 'zh-CN', 'sz': '2000'}) # 20pt t = r.makeelement(qn('a:t'), {}) t.text = '新段落内容' r.append(rPr) r.append(t) new_p.append(r) txBody.append(new_p) ``` --- ## 四、表格处理 ### 4.1 表格实际渲染高度 ≠ shape.height **关键教训**：表格shape设的高度可能不够，内容会溢出。 ```python # 表格有5行，每行0.6英寸 → 实际需要3.0英寸 # 如果shape.height设为2.2，内容会溢出到下面的元素 shape.height = Inches(3.0) # 必须等于或大于内容实际需要的高度 ``` ### 4.2 表格与图片的间距 - 表格底部与下方图片之间至少留 **0.2-0.3英寸** 间距 - 检查方法：读取shape的top + height，计算bottom，确保不重叠 --- ## 五、图片替换工作流 ### 5.1 分段操作原则 **铁律**：在分段PPT上操作，不要先合并完整版再改。 原因： - `copy.deepcopy` 只复制shape的XML引用，不复制图片二进制数据 - 合并时图片被重复嵌入，文件膨胀到20MB+ - 分段文件只有45-50KB，操作快、发送快 ### 5.2 正确流程 ``` 单段脚本生成 → 分段PPT → 在分段PPT里加图/调整 → 所有分段完成后 → 合并完整版 ``` ### 5.3 从原始generate脚本读取正确尺寸 图片占位符的尺寸要从原始生成脚本读取，而不是从合并PPT的文本标签获取。 --- ## 六、Emoji处理 **PowerPoint不支持Unicode emoji**（🧠📚🦾等显示为方块）。 替换方案：用文字标识代替 ```python # ❌ 错误 "🧠 大脑（推理规划）" # ✅ 正确 "[大脑] 推理规划" ``` ### 全量扫描代码 ```python import re emoji_pattern = re.compile('[\U0001F000-\U0001FFFF]') for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame: for para in shape.text_frame.paragraphs: for run in para.runs: if emoji_pattern.search(run.text): print(f'Found emoji: {run.text}') ``` --- ## 七、整体视觉评估 ### 7.1 评估清单（每页修改后检查） - [ ] **左侧vs右侧**：两侧都有内容，没有大片空白 - [ ] **上下居中**：文字在文本框内垂直居中 - [ ] **行间距**：段落行间距让文字呼吸（1.5-2.0x） - [ ] **字体大小**：与区域面积匹配（不空不挤） - [ ] **元素间距**：表格与图片、卡片与卡片之间有合理间距 - [ ] **图片比例**：保持原始比例，不拉伸 - [ ] **图片边距**：不碰圆弧角（≥0.15in） - [ ] **重要内容**：人脸、文字未被裁切 - [ ] **emoji**：无Unicode emoji残留 ### 7.2 常见问题速查 | 问题 | 原因 | 解决方案 | |------|------|----------| | 右侧太空 | 字体太小/行间距太紧 | 放大字体 + 加大行间距(1.5-2.0x) | | 元素重叠 | 表格实际高度溢出 | 检查行数×行高，设shape.height≥实际高度 | | 图片超出页面 | y+h > 7.5英寸 | 上移图片或缩小高度 | | 上方空下方超 | 元素整体偏下 | 整体上移，检查每个元素的bottom | | 文件太大(20MB+) | 合并时图片重复嵌入 | 在分段文件上操作，最后合并 | --- ## 八、验证清单（PPT交付前） - [ ] 全量扫描emoji/特殊字符 - [ ] 每张图片保持原始比例（不拉伸） - [ ] 图片不碰圆弧角（有边距） - [ ] 重要内容（人脸/文字）未被裁切 - [ ] 文字居中、间距合理 - [ ] 合并后总页数正确 - [ ] 分段文件合并后检查重叠/错位 ## 九、图片比例处理原则 ### 核心原则：调高度适配原比例，不裁剪重要内容 **错误做法**：强制裁剪图片到目标比例（2.78:1），导致图表坐标轴、图例等信息丢失 **正确做法**： 1. 保持图片原始比例 2. 通过调整图片高度来适配区域 3. 上下留白（白色背景匹配PPT背景） 4. 图片居中放置 ### 示例 ``` # ❌ 错误：强制裁剪 cropped = img.crop((left, 0, right, height)) # 丢失图例和坐标轴 # ✅ 正确：保持原比例，调整高度 canvas = Image.new('RGB', (target_w, target_h), 'white') scale = target_w / img_w # 按宽度适配 new_h = int(img_h * scale) resized = img.resize((target_w, new_h)) y_offset = (target_h - new_h) // 2 # 垂直居中 canvas.paste(resized, (0, y_offset)) ``` ### 何时可以裁剪 - 照片类图片（人物、场景），裁剪不重要区域 - **绝不裁剪数据图表**的坐标轴、图例、标题 --- ## 十、阿里巴巴普惠体设置（python-pptx） ### 10.1 正确的字体设置方法 **关键**：使用 `run._r` 而非 `run._element` ```python from pptx.oxml.ns import qn from lxml import etree def set_alihei(run, font_size=None, bold=None): """设置字体为阿里巴巴普惠体""" run.font.name = "阿里巴巴普惠体" rPr = run._r.get_or_add_rPr() # 注意：是 _r 不是 _element rFonts = rPr.find(qn('w:rFonts')) if rFonts is None: rFonts = etree.SubElement(rPr, qn('w:rFonts')) rFonts.set(qn('w:eastAsia'), '阿里巴巴普惠体') if font_size: run.font.size = Pt(font_size) if bold is not None: run.font.bold = bold ``` ### 10.2 字号自适应原则 根据文本长度和位置自动调整字号，确保文本框内不空不挤： | 文本类型 | 判断条件 | 字号 | 加粗 | |----------|----------|------|------| | 标题 | top < 1.0英寸 | 28pt | 是 | | 短文本 | len(text) < 15字符 | 22pt | 是 | | 中等文本 | len(text) < 50字符 | 18pt | 否 | | 长文本 | len(text) ≥ 50字符 | 16pt | 否 | ```python for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame and shape.text.strip(): text = shape.text is_title = shape.top < Inches(1.0) for para in shape.text_frame.paragraphs: for run in para.runs: if is_title: set_alihei(run, font_size=28, bold=True) elif len(text) < 15: set_alihei(run, font_size=22, bold=True) elif len(text) < 50: set_alihei(run, font_size=18) else: set_alihei(run, font_size=16) ``` --- ## 十一、图片放置原则（避免遮挡内容） ### 11.1 添加图片前必须检查布局 **铁律**：先分析页面内容布局，找到空白区域再放图，绝不遮挡原有内容。 ```python # 分析页面内容边界 min_left, max_right, min_top, max_bottom = Inches(15), 0, Inches(10), 0 for shape in slide.shapes: if shape.has_text_frame and shape.text.strip(): l, t = shape.left, shape.top r, b = l + shape.width, t + shape.height min_left = min(min_left, l) max_right = max(max_right, r) min_top = min(min_top, t) max_bottom = max(max_bottom, b) # 计算空白区域 if max_bottom < Inches(7): print(f"底部有空白: {max_bottom/914400:.1f}in - 7.5in") ``` ### 11.2 空白区域判断 | 页面状态 | 处理方式 | |----------|----------| | 底部有空白（>1.0in） | 底部居中放小图片（高度0.6-1.2in） | | 右侧有空白（>2.0in） | 右侧放图片，不遮挡左侧内容 | | 满屏无空白 | **不加图**，卡片式/流程式设计不需要图片 | | 有照片占位（如"黄仁勋照片"） | 不加图，保留占位让用户手动添加 | ### 11.3 绝对禁止 - ❌ 遮挡数据卡片（数值、标签） - ❌ 遮挡架构图、流程图 - ❌ 遮挡照片占位区域 - ❌ 在标题区域放图 - ❌ 随意放置图片不考虑布局 ### 11.4 图片尺寸规范 | 放置位置 | 推荐宽度 | 推荐高度 | 说明 | |----------|----------|----------|------| | 底部右侧 | 2.0-2.5in | 0.6-0.9in | 装饰性小图 | | 底部居中 | 2.5-3.0in | 0.9-1.2in | 主题相关图 | | 右侧空白 | 4.0-5.0in | 2.5-3.0in | 较大配图 | --- ## 十二、飞书文件传输限制 ### 12.1 文件大小限制 **飞书单文件上传限制**：约 **25MB** | 文件大小 | 处理方式 | |----------|----------| | < 25MB | 直接发送 | | 25-50MB | 压缩图片后发送 | | > 50MB | 删除图片或分卷压缩 | ### 12.2 压缩图片方法 ```python from PIL import Image import io # 方法1：删除大图片（适合纯文字排版版本） for slide in prs.slides: shapes_to_delete = [s for s in slide.shapes if s.shape_type == 13] for shape in shapes_to_delete: sp = shape._element sp.getparent().remove(sp) # 方法2：压缩图片质量 img = Image.open(img_path) output = io.BytesIO() img.save(output, format='JPEG', quality=70) # 压缩到70%质量 ``` ### 12.3 发送命令 ```bash openclaw message send \ --channel feishu \ --target "ou_xxx" \ --media "/path/to/file.pptx" \ --message "文件说明" ``` --- ## 十三、PPT合并与版本管理 ### 13.1 分段操作原则（再次强调） **铁律**：在分段PPT上操作，不要先合并完整版再改。 原因： - 合并后文件膨胀（23MB+） - 图片可能被重复嵌入 - 修改不便，发送困难 ### 13.2 版本命名规范 | 版本 | 命名 | 说明 | |------|------|------| | 生成版 | `大模型讲座1_P1-P10_红白风格.pptx` | 脚本生成的初始版本 | | 终稿 | `大模型讲座1_P1-P10_红白风格_终稿.pptx` | 确认不再修改的版本 | | 备份 | `大模型讲座1_P1-P10_红白风格_备份.pptx` | 保留的原始备份 | | 完整版 | `大模型讲座1_完整版_红白风格.pptx` | 所有分段合并后的版本 | ### 13.3 旧版本清理 确认终稿后，删除旧版本： - 只保留 `_终稿.pptx` - 删除生成版、备份版 - 减少文件混乱 --- ## 十四、文字排版核心经验（2026-04-06实战总结） ### 14.1 排版三要素联动 **字体大小 + 行间距 + 文本框高度** 三者必须配合调整： | 问题现象 | 原因 | 解决方案 | |----------|------|----------| | 文字太空 | 字号太小 | 放大字号 | | 文字太挤 | 字号太大/行间距太小 | 缩小字号 + 加大行间距 | | 右侧太空 | 字体太小/行间距太紧 | 放大字体 + 加大行间距(1.5-2.0x) | | 上下不居中 | 文本框高度不匹配 | 调整文本框高度 | ### 14.2 视觉评估优先于参数 **不是参数万能，是根据实际情况定的。** 每页修改后检查： - [ ] 文字是否填满区域（不空不挤） - [ ] 行间距是否让文字呼吸（1.5-2.0x适合段落） - [ ] 字体大小是否与区域面积匹配 - [ ] 整体是否上下居中 - [ ] 左侧vs右侧：两侧都有内容，没有大片空白 ### 14.3 卡片式设计的图片策略 **卡片式/流程式设计页面不加图**： - P12（核心理念三卡片）：不加图 - P14（五步工作法流程）：不加图 - P15（三位一体架构）：不加图 - 这类页面以文字和图示为主，不需要额外配图 ### 14.4 字体嵌入与文件大小 | 处理方式 | 文件大小 | 适用场景 | |----------|----------|----------| | 嵌入字体 | 20MB+ | 需要在无字体电脑上完美显示 | | 不嵌入字体 | 100KB-1MB | 文件小，传输快，但需要电脑有对应字体 | **阿里巴巴普惠体**：免费商用，大多数电脑可能没有，建议嵌入或告知用户安装 --- ## 十六、配图搜索实战方法论（2026-04-07浏览器历史复盘） ### 16.1 核心理念 **找图不是"配图"，而是"用图说话"。** 每张图都要和当页内容逻辑匹配，关键词就是页面主题，找不到就换角度再搜。 ### 16.2 按页搜索，逐页击破 不是一次性找完所有图，而是**每做一页搜一轮**。搜索节奏和PPT制作节奏同步： ``` 做P14(五步工作法) → 搜icon → 做P16(黄仁勋) → 搜黄仁勋照片 → ... ``` **原因**： - 边做边搜，关键词精准（知道这页到底需要什么图） - 不会遗漏（每页都过一遍） - 不会过度搜索（找到就停，不过度纠结） ### 16.3 关键词策略：直接用标题或核心概念 用PPT页面标题当搜索词，不绕弯： | PPT页面 | 搜索关键词 | 平台 | |----------|------------|------| | OpenClaw核心理念 | `local-first` `本地优先` | 百度/Google图片 | | 黄仁勋判断 | `黄仁勋` | 百度图片 | | CUDA护城河 | `cuda` | 百度图片 | | 技术演进三阶段 | `聊天机器人` `AI助手` `copilot` | 百度图片 | | 智能投顾 | `智能投顾` | 百度图片 | | 灯塔工厂 | `灯塔工厂` | 百度图片 | | 5G网络智能运维 | `5G网络智能运维` | 百度图片 | ### 16.4 多平台分工 | 平台 | 最适合 | 不适合 | |------|--------|--------| | **百度图片** | 产业概念图、国内行业场景（智能制造、智慧城市） | 技术架构图、国外产品 | | **Google图片** | 技术概念、国外产品截图（Tesla Optimus、Genie） | 中文行业概念 | | **icon-icons.com** | 抽象概念图标（消息、思考、工具、计算、报告） | 实景照片 | | **GitHub** | 开源项目截图、架构图（SciClaw） | 通用场景图 | | **wallhaven** | 高清壁纸/背景图 | 概念图 | | **证券研究所** | 产业架构图、行业图谱 | 人物照片 | | **政府官网(gov.cn)** | 政策、会议照片 | 技术概念图 | ### 16.5 同一主题多角度搜索 找不到合适的就换关键词、换角度： ``` 第一轮：智能反欺诈 → 图不够好 第二轮：智能反欺诈系统 → 还行但想更专业 第三轮：智能金融反欺诈系统 → 找到满意的了 第一轮：人才培养 → 太泛 第二轮：大学教师 → 还行 第三轮：大学教室 → 这张更好 第一轮：开放生态 → 不够技术感 第二轮：开放技术生态 → 还可以 第三轮：open tech env（换Google搜） → 国外的图更有科技感 ``` ### 16.6 批量搜索模式 做完整个章节后，**批量搜索该章节所有页面**： ``` 第二章 行业案例（P20-P41）批量搜索： 11:56 - 智能体、多智能体、multi agent 12:25 - OpenClaw保姆级指南 12:27 - Genie、Tesla Optimus、宇树 12:36 - 智能制造、智能医疗、智能运维 12:42 - 智能投顾、反欺诈 12:45 - 数据中心 12:49 - 人才培养、大学教师、社会服务 12:52 - 清华AI教育 ``` **效率**：一小时内完成整个章节（20+页）的图片搜索。 ### 16.7 搜索顺序建议 | 阶段 | 时间 | 搜索内容 | |------|------|----------| | 封面+目录 | 5分钟 | Logo、主题图 | | 第一章（技术概念） | 20-30分钟 | 概念图标、人物照片、技术架构图 | | 第二章（行业案例） | 40-60分钟 | 行业场景图、案例截图、数据图表 | | 第三章（教育使命） | 20-30分钟 | 教育场景图、大学照片、人物图 | | 总结+附录 | 10分钟 | 补充图、致谢背景 | ### 16.8 搜索记录的价值 浏览器历史记录是**配图过程的审计线索**： - 回溯每张图的来源 - 验证图片是否与内容逻辑关联 - 找到更好的替代图（如果需要替换） 建议保留搜索记录，或在PPT制作日志中记录每张图的来源。 --- ## 十五、重要备注（2026-04-06） ### 15.1 图片功能暂不支持自动化部署 **当前限制**：AI自动生成图片并插入PPT的功能存在以下问题，暂不推荐自动化部署： | 问题 | 说明 | |------|------| | 图片搜索不可靠 | Unsplash被墙、Pexels/Pixabay需API、picsum随机图不相关 | | 图片放置易出错 | 随意放置会遮挡原有内容（数据卡片、架构图、照片占位） | | 图片尺寸难控制 | 比例不匹配、拉伸变形、边距不当 | | 文件大小膨胀 | 原始图片7MB/张，飞书上传限制25MB | **当前建议**： 1. **文字排版自动化**：✅ 支持，可自动设置字体、字号、行间距 2. **图片插入**：❌ 手动添加，AI只负责提供图片建议和位置 3. **终稿确认**：人工审核每页视觉效果后再确认 **未来改进方向**： - 接入稳定的图片搜索API（需API Key） - 实现智能布局分析（自动找空白区域） - 图片自动压缩（保持质量的同时控制文件大小） **实战结论**：目前AI能做好文字排版，但图片处理仍需人工介入。与其花时间做不稳定的自动化，不如专注排版质量，图片留给用户手动添加。 --- ## 十七、图片质量检测与清理（2026-04-07实战总结） ### 17.1 为什么要做图片质量检测 用户手动加完图片后，AI需要**终审**：检查是否有占位符残留、白底过大、尺寸异常等问题。这是PPT交付前的最后一道质量关。 ### 17.2 检测方法（Python自动化） ```python from PIL import Image import os media_dir = 'ppt/media' # 1. 检测灰色占位符（RGB≈E8EEF4） for f in os.listdir(media_dir): img = Image.open(f'{media_dir}/{f}').convert('RGB') w, h = img.size samples = [img.getpixel((x, y)) for x in range(0, w, w//10) for y in range(0, h, h//10)] gray_count = sum(1 for r,g,b in samples if abs(r-232)<15 and abs(g-238)<15 and abs(b-244)<15) if gray_count / len(samples) > 0.5: print(f'⚠️ 灰色占位符: {f}') # 2. 检测大面积空白（白色>85%） white_count = sum(1 for r,g,b in samples if r>250 and g>250 and b>250) if white_count / len(samples) > 0.85: print(f'⚠️ 白底过大: {f}') # 3. 检测尺寸过小（<150px） if w < 150 or h < 150: print(f'⚠️ 尺寸过小: {f} ({w}x{h})') # 4. 检测极端比例（>5:1 或 <1:5） if w/h > 5 or h/w > 5: print(f'⚠️ 比例极端: {f} ({w}x{h})') ``` ### 17.3 残留图片清理 **问题**：合并多个分段PPT后，media目录中可能有**未被任何页面引用**的残留图片。 **检测方法**： ```python from pptx import Presentation import zipfile from lxml import etree # 获取所有被引用的图片 used = set() for i in range(len(prs.slides)): rels = etree.parse(f'ppt/slides/_rels/slide{i+1}.xml.rels') for rel in rels.findall('.//{...}Relationship'): if 'media/' in rel.get('Target', ''): used.add(os.path.basename(rel.get('Target'))) # 找出未使用的 all_imgs = set(os.listdir('ppt/media')) unused = all_imgs - used print(f'残留图片: {unused}') # 可安全删除 ``` **本次实战发现**：54张图片中有4张残留（含1张1.8MB的灰色占位符），清理后文件缩小2MB。 ### 17.4 常见问题速查表 | 问题 | 检测标准 | 处理方式 | |------|----------|----------| | 灰色占位符 | 灰色像素>50%（RGB≈E8EEF4） | 替换为真实图片 | | 白底过大 | 白色像素>85% | 换透明背景PNG或裁剪 | | 尺寸过小 | 任意边<150px | 换大图（至少400px） | | 比例极端 | 宽高比>5:1或<1:5 | 确认是否为设计需要（横条/竖条） | | 残留图片 | 未被任何slide rels引用 | 安全删除 | | 无法读取 | WDP等特殊格式 | 检查是否需要转换 | ### 17.5 omni模型图片审核（视觉能力） 当AI具备视觉能力（mimo-v2-omni）时，可以直接**看图判断**： ```python # 用image工具逐页审核 # prompt: "这张PPT配图的内容是什么？是否与'XXX'主题匹配？有没有模糊/水印/变形？" ``` **omni审核的优势**： - 直接判断图片内容是否与页面主题匹配 - 发现模糊、水印、变形等质量问题 - 识别图片中是否有敏感内容 **注意**：当前mimo-v2-omni的图片分析功能稳定性待提升，建议先用Python检测（17.2节），视觉审核作为辅助。 ### 17.6 完整的图片审核流程 ``` 1. Python自动化检测 ├── 灰色占位符检测 ├── 白底过大检测 ├── 尺寸异常检测 └── 残留图片检测 2. 视觉内容审核（如有omni） ├── 图片内容与页面主题匹配度 ├── 图片质量（清晰度、专业度） └── 敏感内容检查 3. 清理与修复 ├── 删除残留图片 ├── 替换占位符 └── 记录问题清单给用户 ``` --- ## 十八、红白风格设计规范 V2.0（2026-04-10整合） > 基于贾老师PPT深度分析，用于指导红白风格PPT的制作 ### 18.1 配色系统 #### 18.1.1 背景色 | 类型 | 颜色 | 用途 | |------|------|------| | 红色背景 | #E63946 | 封面上半部分、底部装饰条 | | 白色背景 | #FFFFFF | 封面下半部分 | | 浅色背景 | 浅蓝渐变（#F5F7FA 或 #E8F0FA） | 正文页面 | | 卡片背景 | 白色（#FFFFFF） | 数据卡片、内容块 | #### 18.1.2 强调色 | 颜色 | 用途 | |------|------| | 红色（#E63946） | 标题栏、重点文字、序号、边框 | | 黄色（#FFD600） | 关键数据、对比标识（VS）、皇冠图标 | | 蓝色（#1A73E8） | 科技元素、品牌logo、图表柱子 | #### 18.1.3 文字色 | 颜色 | 用途 | |------|------| | 白色（#FFFFFF） | 深色背景上的标题 | | 黑色（#1A1A2E） | 浅色背景上的正文 | | 红色（#E63946） | 强调文字、标题 | | 灰色（#6B7B8D） | 辅助说明文字 | ### 18.2 布局类型 #### 18.2.1 封面页（红白双色分区） - **布局**：上红下白双色分区 - **红色区域（56%高度）**： - 左上角小字：课程归属（白色，14pt） - 中间：模块编号（白色，54pt，粗体） - 下方：课程主标题（白色，44pt，粗体） - 底部：关键词（白色，18pt） - **白色区域（44%高度）**： - 讲师姓名（黑色，36pt，粗体） - 公司/职位（灰色，16pt） - **底部红色装饰条**：高度约0.38英寸 - **文字颜色**：红色区域内白色，白色区域内黑色/灰色 #### 18.2.1b 尾页（红白双色分区） - **布局**：上红下白双色分区 + 底部红色装饰条 - **红色区域（50%高度）**： - "谢谢！"（白色，72pt，粗体，居中） - 位置：top≈1500000（红色区域内偏上） - **白色区域（50%高度）**： - 模块标题（黑色，28pt，居中） - 位置：top≈4500000（白色区域内） - **底部红色装饰条**：高度约0.38英寸 - **核心原则**： - 两行文字作为整体居中分布 - "谢谢"在红色背景上（白色） - 模块标题在白色背景上（黑色） - 两行文字要分开适当距离，避免挤在一起 #### 18.2.2 正文页（红色标题栏） - **布局**：顶部红色标题栏 + 下方浅色背景，双栏布局 - **红色标题栏**：高度约0.56英寸（822960 EMU），颜色 #E63946 - **标题文字**：白色，28pt，粗体，位于红色标题栏内 - **正文区域**：浅色背景，左右两个白色卡片并排 - **卡片内部元素**： - 小标题：黑色，20pt，粗体 - 红色横线装饰：位于小标题下方，右侧拉长2倍 - 内容：黑色，20pt，1.5倍行距（line_spacing=1.5），段后间距0 - **核心原则**： - 红色标题栏内文字必须为白色 - 红色横线适当下移，避免与标题重叠 - 内容文字设置自动换行（word_wrap=True） - 文字超出文本框时，缩小字号（18pt） #### 18.2.3 目录页（卡片式） - **布局**：顶部红色标题栏 + 下方3个白色卡片水平排列 - **红色标题栏**："目录"（白色，32pt，粗体，左上角） - **卡片参数**： - 卡片数量：3个，左右均匀分布 - 卡片高度：占内容区域85%，上下居中 - 卡片样式：白色背景 + 红色边框（1.5pt） - **卡片内部元素**： - 序号：红色方形块（#E63946）+ 白色数字（36pt，粗体，居中） - 标题：黑色（20pt，粗体），位于序号下方 - 红色横线装饰：位于标题下方 - 内容：灰色（20pt，2倍行距），列点形式 - **核心原则**： - 卡片上下居中，不要偏上或偏下 - 红色横线和内容文字要与标题保持适当距离，避免重叠 - 字体统一20pt，行距2倍 #### 18.2.4 章节页（左红右白分栏） - **布局**：左侧红色大色块 + 右侧白色区域 - **红色区域（左侧37.5%宽度）**： - 序号：白色，72pt，粗体（如"01"、"02"、"03"） - 章节标题：白色，36pt，粗体 - 位置：左侧整体上下居中 - **白色区域（右侧62.5%宽度）**： - "本章要点"：黑色，28pt，粗体 - 要点内容：黑色，24pt，2倍行距（line_spacing=2.0），段后间距0 - 位置：右侧整体上下居中 - **核心原则**： - 左右两侧内容各自整体居中 - 序号和标题在红色区域内，白色文字 - "本章要点"和内容在白色区域内，黑色文字 - 要点内容行距2倍，段后间距0 #### 18.2.5 卡片式水平排列 - **布局**：2-4个白色卡片水平并排 - **卡片内部**：上文下图 或 上图下文 - **装饰**：白色背景 + 轻微阴影 + 红色边框（重点卡片用蓝色边框） - **VS对比**：红色"VS"图标分隔对比卡片 #### 18.2.4 左图右文 - **布局**：左侧图片区（50-60%）+ 右侧文字区（40-50%） - **图片类型**：创意插画、场景照片、数据图表 - **文字层级**：红色标题 → 黑色正文 → 灰色辅助 #### 18.2.5 三段式左图右文 - **布局**：页面分为上中下三段，每段左侧图片 + 右侧文字 - **适用**：介绍3个并列概念/案例 - **特点**：图文一一对应，结构清晰 #### 18.2.6 分块式布局 - **布局**：多个功能区块组合（左/中/右 或 上/中/下） - **元素**：按钮式色块 + 图标 + 文字框 - **装饰**：红色/黄色色块、大脑图标、VS标识 ### 18.3 图文配比规范 | 页面类型 | 图片占比 | 文字占比 | 说明 | |---------|---------|---------|------| | 卡片式 | 40-50% | 50-60% | 卡片内图文1:1 | | 左图右文 | 50-60% | 40-50% | 图片为主 | | 三段式 | 40-45% | 55-60% | 图文均衡 | | 数据页 | 10% | 90% | 以表格/文字为主 | | 流程图 | 60% | 40% | 图片/图标为主 | ### 18.4 字体层级 | 层级 | 字号 | 颜色 | 用途 | |------|------|------|------| | 一级 | 48-64pt | 白色/红色 | 页面大标题 | | 二级 | 28-36pt | 红色/黑色 | 板块标题、卡片标题 | | 三级 | 20-24pt | 黑色 | 正文要点 | | 四级 | 14-18pt | 灰色/黑色 | 辅助说明、标签 | | 五级 | 12pt | 灰色 | 最小补充文字 | ### 18.5 装饰元素 #### 18.5.1 必备元素 - **红色标题栏**：顶部横条（高度约1.2英寸） - **圆形序号框**：红色填充 + 白色数字 - **圆角矩形卡片**：白色背景 + 红色/蓝色边框 - **VS图标**：红色圆形 + 白色"VS"文字 #### 18.5.2 科技感元素 - **大脑图标**：象征AI/思维 - **齿轮/电路图标**：象征技术 - **箭头流程线**：连接流程步骤 - **皇冠图标**：象征等级/领先 ### 18.6 快速应用模板 #### 模板A：卡片式（2卡片对比） ``` [红色标题栏] [卡片1: 上图下文] VS [卡片2: 上图下文] ``` #### 模板B：左图右文 ``` [红色标题栏] [图片区 55%] [文字区 45%] ``` #### 模板C：三段式 ``` [红色标题栏] [图1 + 文1] [图2 + 文2] [图3 + 文3] ``` #### 模板D：分块式 ``` [红色标题栏] [按钮1] [按钮2] [按钮3] [图表/流程图] [说明文字] ``` ### 18.7 python-pptx实现代码示例 ```python from pptx.util import Inches, Pt from pptx.dml.color import RGBColor # 颜色定义 class Colors: DARK_BLUE_START = RGBColor(0x0A, 0x16, 0x28) # 深蓝渐变起始 DARK_BLUE_END = RGBColor(0x1A, 0x3A, 0x5C) # 深蓝渐变结束 LIGHT_BLUE = RGBColor(0xF5, 0xF7, 0xFA) # 浅蓝背景 RED = RGBColor(0xE6, 0x39, 0x46) # 红色强调 YELLOW = RGBColor(0xFF, 0xD6, 0x00) # 黄色 BLUE = RGBColor(0x1A, 0x73, 0xE8) # 蓝色 WHITE = RGBColor(0xFF, 0xFF, 0xFF) BLACK = RGBColor(0x1A, 0x1A, 0x2E) GRAY = RGBColor(0x6B, 0x7B, 0x8D) # 设置渐变背景 def set_slide_background_gradient(slide, color1, color2): background = slide.background fill = background.fill fill.gradient() fill._fill.gradient_stops[0].color.rgb = color1 fill._fill.gradient_stops[1].color.rgb = color2 # 设置纯色背景 def set_slide_background_solid(slide, color): background = slide.background fill = background.fill fill.solid() fill.fore_color.rgb = color # 添加红色标题栏 def add_red_header(slide, title): add_shape(slide, Inches(0), Inches(0), Inches(13.33), Inches(0.8), Colors.RED) add_text_box(slide, Inches(0.5), Inches(0.1), Inches(12), Inches(0.6), title, 28, Colors.WHITE, True) # 添加白色圆角卡片 def add_white_card(slide, left, top, width, height): return add_rounded_rectangle(slide, left, top, width, height, Colors.WHITE) # 添加VS对比图标 def add_vs_icon(slide, left, top): shape = add_shape(slide, left, top, Inches(1), Inches(1), Colors.RED) add_text_box(slide, left, top + 0.15, Inches(1), Inches(0.7), "VS", 28, Colors.WHITE, True, PP_ALIGN.CENTER) ``` --- **版本**: V2.0（整合版） **更新日期**: 2026-04-10 **来源**: 红白风格设计规范V2.0 + ppt-pandora实战经验 ---

path: SKILL_青椒课堂课程转化专用备份.md
content: ---
name: ppt-pandora
description: >
  PPT完整制作流程：从素材收集、大纲规划，到图片搜索/裁剪/插入、文字排版调整（字体大小/行间距/位置）、
  表格处理、整体视觉评估，直到最终验证。支持红白风格等专业PPT的全流程制作。
metadata: {"openclaw": {"emoji": "📊", "os": ["darwin", "linux"]}}
---

# PPT完整制作流程

## 一、素材收集与规划

### 1.1 内容来源优先级
1. **青椒课堂**（qingjiaoclass.com）— 实训课程内容
2. **权威官方报道**（gov.cn、news.cn、people.com.cn）— 政策、数据、事件
3. **证券研究所报告** — 产业架构图、行业数据图表（极其权威专业）
4. **Pexels免费图库** — 通用场景照片
5. **AI生成图片** — 无版权风险，但质量不稳定

### 1.2 贾老师找图法（内容→来源→关联→配图）
1. 看PPT页面的**核心主题和引用内容**（政策引领？技术趋势？行业案例？）
2. 搜索**引用的原话**，找到权威官方报道
3. 从报道里找**关联事件**（上下文提到的会议/政策/人物/数据）
4. 用关联事件去搜对应的图片

**为什么有效**：图片和内容有逻辑关联，不是随便配的免费图。

**示例**：
- P3 讲"政策引领+习主席指示" → 搜习主席原话 → 找到发改委文章 → 文章提到"二十届三中全会" → 搜该会议照片
- P4 讲"十五五规划+人工智能+" → 搜十五五报道 → gov.cn文章有李强主持编制会议照片
- P6 讲"中国AI产业" → 搜"AI产业层级架构" → 华西证券研究所报告图片

### 1.3 特殊图片渠道
- **gov.cn图片路径**：`./W0xxxxxxxxxx_ORIGIN.JPG`（拼接完整URL）
- **人民网图片路径**：`/NMediaFile/xxxxx/MAINxxxxxxxx.jpg`
- **证券研究所图片**：搜索"XX证券 AI产业"或"XX证券 行业图谱"

---

## 二、图片裁剪与适配

### 2.1 核心原则
1. **绝不拉伸**，保持原始宽高比
2. 裁剪时**保留重要内容**（人脸、文字不能切掉）
3. 从**不重要部分**裁切（下半身、留白、背景）
4. 卡片圆弧角 → **必须留边距**（≥0.15英寸）

### 2.2 裁剪策略速查表

| 场景 | 策略 |
|------|------|
| 竖图→横卡片 | 裁掉不重要部分（下半身/背景），保留上半部分，居中放置 |
| 文字在底部 | 裁上方留白，让文字靠上 |
| 人脸照片 | 用image工具定位脸坐标，以脸为中心裁剪 |
| 横图→横卡片 | 从上下等比裁切，保持居中 |
| 比例接近但不匹配 | 微调裁切量，尽量保留主要内容 |
| 图片比预留区域小 | 按比例缩放后居中放置，四周留白，绝不拉伸 |

### 2.3 边距规范

| 边距大小 | 适用场景 |
|----------|----------|
| 0.15英寸 | 最小值，刚好避免直角碰圆弧 |
| 0.3英寸 | 通用推荐值 |
| 0.5英寸 | 需要明显留白时 |

### 2.4 Python代码示例

```python
from pptx.util import Inches

# 图片在卡片区域内带边距
card_left, card_top, card_w, card_h = 0.8, 1.8, 5.0, 2.5
margin = 0.15

img_left = card_left + margin
img_top = card_top + margin
img_w = card_w - 2 * margin
img_h = img_w / image_aspect_ratio  # 等比计算高度

# 居中在卡片区域内
img_top = card_top + (card_h - img_h) / 2

slide.shapes.add_picture(img_path, Inches(img_left), Inches(img_top), 
                         Inches(img_w), Inches(img_h))
```

---

## 三、文字排版调整

### 3.1 核心三要素：字体大小 + 行间距 + 文本框高度

**三者必须配合调整**，只改一个参数往往视觉效果不好。

| 场景 | 字体大小 | 行间距 | 文本框高度 |
|------|----------|--------|------------|
| 正文段落（填满区域） | 18-20pt | 1.5-2.0x | 匹配内容 |
| 数据卡片标签 | 16pt | 1.0x | 自适应 |
| 数据卡片数值 | 28pt | 1.0x | 自适应 |
| 数据卡片单位 | 14pt | 1.0x | 自适应 |
| 标题 | 24-32pt | 1.0x | 自适应 |

### 3.2 视觉评估原则
**不是参数万能，是根据实际情况定的。**

判断标准：
- 文字是否填满区域（不空不挤）
- 行间距是否让文字呼吸（1.5-2.0x适合段落）
- 字体大小是否与区域面积匹配
- 整体是否上下居中

### 3.3 主副标题合并
```python
# 用破折号连接，解决右侧太空问题
shape.text_frame.paragraphs[0].text = f'{main_title}——{subtitle}'
# 删除旧的副标题shape
sub_shape._element.getparent().remove(sub_shape._element)
```

### 3.4 文字垂直居中（XML方式）
```python
from pptx.oxml.ns import qn
sp = shape._element
for child in sp:
    tag = child.tag.split('}')[-1] if '}' in child.tag else child.tag
    if tag == 'txBody':
        for sub in child:
            subtag = sub.tag.split('}')[-1] if '}' in sub.tag else sub.tag
            if subtag == 'bodyPr':
                sub.set('anchor', 'ctr')  # 垂直居中
```

### 3.5 python-pptx 添加新段落
```python
# ❌ 错误：paragraphs[3] 访问不存在的段落不会自动创建
# ✅ 正确：手动创建XML paragraph元素

from pptx.oxml.ns import qn

txBody = shape.text_frame._txBody
new_p = txBody.makeelement(qn('a:p'), {})
r = new_p.makeelement(qn('a:r'), {})
rPr = r.makeelement(qn('a:rPr'), {'lang': 'zh-CN', 'sz': '2000'})  # 20pt
t = r.makeelement(qn('a:t'), {})
t.text = '新段落内容'
r.append(rPr)
r.append(t)
new_p.append(r)
txBody.append(new_p)
```

---

## 四、表格处理

### 4.1 表格实际渲染高度 ≠ shape.height

**关键教训**：表格shape设的高度可能不够，内容会溢出。

```python
# 表格有5行，每行0.6英寸 → 实际需要3.0英寸
# 如果shape.height设为2.2，内容会溢出到下面的元素
shape.height = Inches(3.0)  # 必须等于或大于内容实际需要的高度
```

### 4.2 表格与图片的间距
- 表格底部与下方图片之间至少留 **0.2-0.3英寸** 间距
- 检查方法：读取shape的top + height，计算bottom，确保不重叠

---

## 五、图片替换工作流

### 5.1 分段操作原则
**铁律**：在分段PPT上操作，不要先合并完整版再改。

原因：
- `copy.deepcopy` 只复制shape的XML引用，不复制图片二进制数据
- 合并时图片被重复嵌入，文件膨胀到20MB+
- 分段文件只有45-50KB，操作快、发送快

### 5.2 正确流程
```
单段脚本生成 → 分段PPT → 在分段PPT里加图/调整 → 所有分段完成后 → 合并完整版
```

### 5.3 从原始generate脚本读取正确尺寸
图片占位符的尺寸要从原始生成脚本读取，而不是从合并PPT的文本标签获取。

---

## 六、Emoji处理

**PowerPoint不支持Unicode emoji**（🧠📚🦾等显示为方块）。

替换方案：用文字标识代替
```python
# ❌ 错误
"🧠 大脑（推理规划）"
# ✅ 正确
"[大脑] 推理规划"
```

### 全量扫描代码
```python
import re
emoji_pattern = re.compile('[\U0001F000-\U0001FFFF]')
for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            for para in shape.text_frame.paragraphs:
                for run in para.runs:
                    if emoji_pattern.search(run.text):
                        print(f'Found emoji: {run.text}')
```

---

## 七、整体视觉评估

### 7.1 评估清单（每页修改后检查）
- [ ] **左侧vs右侧**：两侧都有内容，没有大片空白
- [ ] **上下居中**：文字在文本框内垂直居中
- [ ] **行间距**：段落行间距让文字呼吸（1.5-2.0x）
- [ ] **字体大小**：与区域面积匹配（不空不挤）
- [ ] **元素间距**：表格与图片、卡片与卡片之间有合理间距
- [ ] **图片比例**：保持原始比例，不拉伸
- [ ] **图片边距**：不碰圆弧角（≥0.15in）
- [ ] **重要内容**：人脸、文字未被裁切
- [ ] **emoji**：无Unicode emoji残留

### 7.2 常见问题速查

| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 右侧太空 | 字体太小/行间距太紧 | 放大字体 + 加大行间距(1.5-2.0x) |
| 元素重叠 | 表格实际高度溢出 | 检查行数×行高，设shape.height≥实际高度 |
| 图片超出页面 | y+h > 7.5英寸 | 上移图片或缩小高度 |
| 上方空下方超 | 元素整体偏下 | 整体上移，检查每个元素的bottom |
| 文件太大(20MB+) | 合并时图片重复嵌入 | 在分段文件上操作，最后合并 |

---

## 八、验证清单（PPT交付前）

- [ ] 全量扫描emoji/特殊字符
- [ ] 每张图片保持原始比例（不拉伸）
- [ ] 图片不碰圆弧角（有边距）
- [ ] 重要内容（人脸/文字）未被裁切
- [ ] 文字居中、间距合理
- [ ] 合并后总页数正确
- [ ] 分段文件合并后检查重叠/错位

## 九、图片比例处理原则

### 核心原则：调高度适配原比例，不裁剪重要内容

**错误做法**：强制裁剪图片到目标比例（2.78:1），导致图表坐标轴、图例等信息丢失

**正确做法**：
1. 保持图片原始比例
2. 通过调整图片高度来适配区域
3. 上下留白（白色背景匹配PPT背景）
4. 图片居中放置

### 示例
```
# ❌ 错误：强制裁剪
cropped = img.crop((left, 0, right, height))  # 丢失图例和坐标轴

# ✅ 正确：保持原比例，调整高度
canvas = Image.new('RGB', (target_w, target_h), 'white')
scale = target_w / img_w  # 按宽度适配
new_h = int(img_h * scale)
resized = img.resize((target_w, new_h))
y_offset = (target_h - new_h) // 2  # 垂直居中
canvas.paste(resized, (0, y_offset))
```

### 何时可以裁剪
- 照片类图片（人物、场景），裁剪不重要区域
- **绝不裁剪数据图表**的坐标轴、图例、标题

---

## 十、阿里巴巴普惠体设置（python-pptx）

### 10.1 正确的字体设置方法

**关键**：使用 `run._r` 而非 `run._element`

```python
from pptx.oxml.ns import qn
from lxml import etree

def set_alihei(run, font_size=None, bold=None):
    """设置字体为阿里巴巴普惠体"""
    run.font.name = "阿里巴巴普惠体"
    rPr = run._r.get_or_add_rPr()  # 注意：是 _r 不是 _element
    rFonts = rPr.find(qn('w:rFonts'))
    if rFonts is None:
        rFonts = etree.SubElement(rPr, qn('w:rFonts'))
    rFonts.set(qn('w:eastAsia'), '阿里巴巴普惠体')
    if font_size:
        run.font.size = Pt(font_size)
    if bold is not None:
        run.font.bold = bold
```

### 10.2 字号自适应原则

根据文本长度和位置自动调整字号，确保文本框内不空不挤：

| 文本类型 | 判断条件 | 字号 | 加粗 |
|----------|----------|------|------|
| 标题 | top < 1.0英寸 | 28pt | 是 |
| 短文本 | len(text) < 15字符 | 22pt | 是 |
| 中等文本 | len(text) < 50字符 | 18pt | 否 |
| 长文本 | len(text) ≥ 50字符 | 16pt | 否 |

```python
for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame and shape.text.strip():
            text = shape.text
            is_title = shape.top < Inches(1.0)
            for para in shape.text_frame.paragraphs:
                for run in para.runs:
                    if is_title:
                        set_alihei(run, font_size=28, bold=True)
                    elif len(text) < 15:
                        set_alihei(run, font_size=22, bold=True)
                    elif len(text) < 50:
                        set_alihei(run, font_size=18)
                    else:
                        set_alihei(run, font_size=16)
```

---

## 十一、图片放置原则（避免遮挡内容）

### 11.1 添加图片前必须检查布局

**铁律**：先分析页面内容布局，找到空白区域再放图，绝不遮挡原有内容。

```python
# 分析页面内容边界
min_left, max_right, min_top, max_bottom = Inches(15), 0, Inches(10), 0
for shape in slide.shapes:
    if shape.has_text_frame and shape.text.strip():
        l, t = shape.left, shape.top
        r, b = l + shape.width, t + shape.height
        min_left = min(min_left, l)
        max_right = max(max_right, r)
        min_top = min(min_top, t)
        max_bottom = max(max_bottom, b)

# 计算空白区域
if max_bottom < Inches(7):
    print(f"底部有空白: {max_bottom/914400:.1f}in - 7.5in")
```

### 11.2 空白区域判断

| 页面状态 | 处理方式 |
|----------|----------|
| 底部有空白（>1.0in） | 底部居中放小图片（高度0.6-1.2in） |
| 右侧有空白（>2.0in） | 右侧放图片，不遮挡左侧内容 |
| 满屏无空白 | **不加图**，卡片式/流程式设计不需要图片 |
| 有照片占位（如"黄仁勋照片"） | 不加图，保留占位让用户手动添加 |

### 11.3 绝对禁止

- ❌ 遮挡数据卡片（数值、标签）
- ❌ 遮挡架构图、流程图
- ❌ 遮挡照片占位区域
- ❌ 在标题区域放图
- ❌ 随意放置图片不考虑布局

### 11.4 图片尺寸规范

| 放置位置 | 推荐宽度 | 推荐高度 | 说明 |
|----------|----------|----------|------|
| 底部右侧 | 2.0-2.5in | 0.6-0.9in | 装饰性小图 |
| 底部居中 | 2.5-3.0in | 0.9-1.2in | 主题相关图 |
| 右侧空白 | 4.0-5.0in | 2.5-3.0in | 较大配图 |

---

## 十二、飞书文件传输限制

### 12.1 文件大小限制

**飞书单文件上传限制**：约 **25MB**

| 文件大小 | 处理方式 |
|----------|----------|
| < 25MB | 直接发送 |
| 25-50MB | 压缩图片后发送 |
| > 50MB | 删除图片或分卷压缩 |

### 12.2 压缩图片方法

```python
from PIL import Image
import io

# 方法1：删除大图片（适合纯文字排版版本）
for slide in prs.slides:
    shapes_to_delete = [s for s in slide.shapes if s.shape_type == 13]
    for shape in shapes_to_delete:
        sp = shape._element
        sp.getparent().remove(sp)

# 方法2：压缩图片质量
img = Image.open(img_path)
output = io.BytesIO()
img.save(output, format='JPEG', quality=70)  # 压缩到70%质量
```

### 12.3 发送命令

```bash
openclaw message send \
  --channel feishu \
  --target "ou_xxx" \
  --media "/path/to/file.pptx" \
  --message "文件说明"
```

---

## 十三、PPT合并与版本管理

### 13.1 分段操作原则（再次强调）

**铁律**：在分段PPT上操作，不要先合并完整版再改。

原因：
- 合并后文件膨胀（23MB+）
- 图片可能被重复嵌入
- 修改不便，发送困难

### 13.2 版本命名规范

| 版本 | 命名 | 说明 |
|------|------|------|
| 生成版 | `大模型讲座1_P1-P10_红白风格.pptx` | 脚本生成的初始版本 |
| 终稿 | `大模型讲座1_P1-P10_红白风格_终稿.pptx` | 确认不再修改的版本 |
| 备份 | `大模型讲座1_P1-P10_红白风格_备份.pptx` | 保留的原始备份 |
| 完整版 | `大模型讲座1_完整版_红白风格.pptx` | 所有分段合并后的版本 |

### 13.3 旧版本清理

确认终稿后，删除旧版本：
- 只保留 `_终稿.pptx`
- 删除生成版、备份版
- 减少文件混乱

---

## 十四、文字排版核心经验（2026-04-06实战总结）

### 14.1 排版三要素联动

**字体大小 + 行间距 + 文本框高度** 三者必须配合调整：

| 问题现象 | 原因 | 解决方案 |
|----------|------|----------|
| 文字太空 | 字号太小 | 放大字号 |
| 文字太挤 | 字号太大/行间距太小 | 缩小字号 + 加大行间距 |
| 右侧太空 | 字体太小/行间距太紧 | 放大字体 + 加大行间距(1.5-2.0x) |
| 上下不居中 | 文本框高度不匹配 | 调整文本框高度 |

### 14.2 视觉评估优先于参数

**不是参数万能，是根据实际情况定的。**

每页修改后检查：
- [ ] 文字是否填满区域（不空不挤）
- [ ] 行间距是否让文字呼吸（1.5-2.0x适合段落）
- [ ] 字体大小是否与区域面积匹配
- [ ] 整体是否上下居中
- [ ] 左侧vs右侧：两侧都有内容，没有大片空白

### 14.3 卡片式设计的图片策略

**卡片式/流程式设计页面不加图**：
- P12（核心理念三卡片）：不加图
- P14（五步工作法流程）：不加图
- P15（三位一体架构）：不加图
- 这类页面以文字和图示为主，不需要额外配图

### 14.4 字体嵌入与文件大小

| 处理方式 | 文件大小 | 适用场景 |
|----------|----------|----------|
| 嵌入字体 | 20MB+ | 需要在无字体电脑上完美显示 |
| 不嵌入字体 | 100KB-1MB | 文件小，传输快，但需要电脑有对应字体 |

**阿里巴巴普惠体**：免费商用，大多数电脑可能没有，建议嵌入或告知用户安装

---

## 十六、配图搜索实战方法论（2026-04-07浏览器历史复盘）

### 16.1 核心理念
**找图不是"配图"，而是"用图说话"。** 每张图都要和当页内容逻辑匹配，关键词就是页面主题，找不到就换角度再搜。

### 16.2 按页搜索，逐页击破
不是一次性找完所有图，而是**每做一页搜一轮**。搜索节奏和PPT制作节奏同步：
```
做P14(五步工作法) → 搜icon → 做P16(黄仁勋) → 搜黄仁勋照片 → ...
```

**原因**：
- 边做边搜，关键词精准（知道这页到底需要什么图）
- 不会遗漏（每页都过一遍）
- 不会过度搜索（找到就停，不过度纠结）

### 16.3 关键词策略：直接用标题或核心概念
用PPT页面标题当搜索词，不绕弯：

| PPT页面 | 搜索关键词 | 平台 |
|----------|------------|------|
| OpenClaw核心理念 | `local-first` `本地优先` | 百度/Google图片 |
| 黄仁勋判断 | `黄仁勋` | 百度图片 |
| CUDA护城河 | `cuda` | 百度图片 |
| 技术演进三阶段 | `聊天机器人` `AI助手` `copilot` | 百度图片 |
| 智能投顾 | `智能投顾` | 百度图片 |
| 灯塔工厂 | `灯塔工厂` | 百度图片 |
| 5G网络智能运维 | `5G网络智能运维` | 百度图片 |

### 16.4 多平台分工

| 平台 | 最适合 | 不适合 |
|------|--------|--------|
| **百度图片** | 产业概念图、国内行业场景（智能制造、智慧城市） | 技术架构图、国外产品 |
| **Google图片** | 技术概念、国外产品截图（Tesla Optimus、Genie） | 中文行业概念 |
| **icon-icons.com** | 抽象概念图标（消息、思考、工具、计算、报告） | 实景照片 |
| **GitHub** | 开源项目截图、架构图（SciClaw） | 通用场景图 |
| **wallhaven** | 高清壁纸/背景图 | 概念图 |
| **证券研究所** | 产业架构图、行业图谱 | 人物照片 |
| **政府官网(gov.cn)** | 政策、会议照片 | 技术概念图 |

### 16.5 同一主题多角度搜索
找不到合适的就换关键词、换角度：

```
第一轮：智能反欺诈
  → 图不够好
第二轮：智能反欺诈系统
  → 还行但想更专业
第三轮：智能金融反欺诈系统
  → 找到满意的了

第一轮：人才培养
  → 太泛
第二轮：大学教师
  → 还行
第三轮：大学教室
  → 这张更好

第一轮：开放生态
  → 不够技术感
第二轮：开放技术生态
  → 还可以
第三轮：open tech env（换Google搜）
  → 国外的图更有科技感
```

### 16.6 批量搜索模式
做完整个章节后，**批量搜索该章节所有页面**：

```
第二章 行业案例（P20-P41）批量搜索：
  11:56 - 智能体、多智能体、multi agent
  12:25 - OpenClaw保姆级指南
  12:27 - Genie、Tesla Optimus、宇树
  12:36 - 智能制造、智能医疗、智能运维
  12:42 - 智能投顾、反欺诈
  12:45 - 数据中心
  12:49 - 人才培养、大学教师、社会服务
  12:52 - 清华AI教育
```

**效率**：一小时内完成整个章节（20+页）的图片搜索。

### 16.7 搜索顺序建议

| 阶段 | 时间 | 搜索内容 |
|------|------|----------|
| 封面+目录 | 5分钟 | Logo、主题图 |
| 第一章（技术概念） | 20-30分钟 | 概念图标、人物照片、技术架构图 |
| 第二章（行业案例） | 40-60分钟 | 行业场景图、案例截图、数据图表 |
| 第三章（教育使命） | 20-30分钟 | 教育场景图、大学照片、人物图 |
| 总结+附录 | 10分钟 | 补充图、致谢背景 |

### 16.8 搜索记录的价值
浏览器历史记录是**配图过程的审计线索**：
- 回溯每张图的来源
- 验证图片是否与内容逻辑关联
- 找到更好的替代图（如果需要替换）

建议保留搜索记录，或在PPT制作日志中记录每张图的来源。

---

## 十五、重要备注（2026-04-06）

### 15.1 图片功能暂不支持自动化部署

**当前限制**：AI自动生成图片并插入PPT的功能存在以下问题，暂不推荐自动化部署：

| 问题 | 说明 |
|------|------|
| 图片搜索不可靠 | Unsplash被墙、Pexels/Pixabay需API、picsum随机图不相关 |
| 图片放置易出错 | 随意放置会遮挡原有内容（数据卡片、架构图、照片占位） |
| 图片尺寸难控制 | 比例不匹配、拉伸变形、边距不当 |
| 文件大小膨胀 | 原始图片7MB/张，飞书上传限制25MB |

**当前建议**：
1. **文字排版自动化**：✅ 支持，可自动设置字体、字号、行间距
2. **图片插入**：❌ 手动添加，AI只负责提供图片建议和位置
3. **终稿确认**：人工审核每页视觉效果后再确认

**未来改进方向**：
- 接入稳定的图片搜索API（需API Key）
- 实现智能布局分析（自动找空白区域）
- 图片自动压缩（保持质量的同时控制文件大小）

**实战结论**：目前AI能做好文字排版，但图片处理仍需人工介入。与其花时间做不稳定的自动化，不如专注排版质量，图片留给用户手动添加。

---

## 十七、图片质量检测与清理（2026-04-07实战总结）

### 17.1 为什么要做图片质量检测
用户手动加完图片后，AI需要**终审**：检查是否有占位符残留、白底过大、尺寸异常等问题。这是PPT交付前的最后一道质量关。

### 17.2 检测方法（Python自动化）

```python
from PIL import Image
import os

media_dir = 'ppt/media'

# 1. 检测灰色占位符（RGB≈E8EEF4）
for f in os.listdir(media_dir):
    img = Image.open(f'{media_dir}/{f}').convert('RGB')
    w, h = img.size
    samples = [img.getpixel((x, y)) for x in range(0, w, w//10) for y in range(0, h, h//10)]
    gray_count = sum(1 for r,g,b in samples if abs(r-232)<15 and abs(g-238)<15 and abs(b-244)<15)
    if gray_count / len(samples) > 0.5:
        print(f'⚠️ 灰色占位符: {f}')

# 2. 检测大面积空白（白色>85%）
    white_count = sum(1 for r,g,b in samples if r>250 and g>250 and b>250)
    if white_count / len(samples) > 0.85:
        print(f'⚠️ 白底过大: {f}')

# 3. 检测尺寸过小（<150px）
    if w < 150 or h < 150:
        print(f'⚠️ 尺寸过小: {f} ({w}x{h})')

# 4. 检测极端比例（>5:1 或 <1:5）
    if w/h > 5 or h/w > 5:
        print(f'⚠️ 比例极端: {f} ({w}x{h})')
```

### 17.3 残留图片清理

**问题**：合并多个分段PPT后，media目录中可能有**未被任何页面引用**的残留图片。

**检测方法**：
```python
from pptx import Presentation
import zipfile
from lxml import etree

# 获取所有被引用的图片
used = set()
for i in range(len(prs.slides)):
    rels = etree.parse(f'ppt/slides/_rels/slide{i+1}.xml.rels')
    for rel in rels.findall('.//{...}Relationship'):
        if 'media/' in rel.get('Target', ''):
            used.add(os.path.basename(rel.get('Target')))

# 找出未使用的
all_imgs = set(os.listdir('ppt/media'))
unused = all_imgs - used
print(f'残留图片: {unused}')  # 可安全删除
```

**本次实战发现**：54张图片中有4张残留（含1张1.8MB的灰色占位符），清理后文件缩小2MB。

### 17.4 常见问题速查表

| 问题 | 检测标准 | 处理方式 |
|------|----------|----------|
| 灰色占位符 | 灰色像素>50%（RGB≈E8EEF4） | 替换为真实图片 |
| 白底过大 | 白色像素>85% | 换透明背景PNG或裁剪 |
| 尺寸过小 | 任意边<150px | 换大图（至少400px） |
| 比例极端 | 宽高比>5:1或<1:5 | 确认是否为设计需要（横条/竖条） |
| 残留图片 | 未被任何slide rels引用 | 安全删除 |
| 无法读取 | WDP等特殊格式 | 检查是否需要转换 |

### 17.5 omni模型图片审核（视觉能力）

当AI具备视觉能力（mimo-v2-omni）时，可以直接**看图判断**：

```python
# 用image工具逐页审核
# prompt: "这张PPT配图的内容是什么？是否与'XXX'主题匹配？有没有模糊/水印/变形？"
```

**omni审核的优势**：
- 直接判断图片内容是否与页面主题匹配
- 发现模糊、水印、变形等质量问题
- 识别图片中是否有敏感内容

**注意**：当前mimo-v2-omni的图片分析功能稳定性待提升，建议先用Python检测（17.2节），视觉审核作为辅助。

### 17.6 完整的图片审核流程

```
1. Python自动化检测
   ├── 灰色占位符检测
   ├── 白底过大检测
   ├── 尺寸异常检测
   └── 残留图片检测

2. 视觉内容审核（如有omni）
   ├── 图片内容与页面主题匹配度
   ├── 图片质量（清晰度、专业度）
   └── 敏感内容检查

3. 清理与修复
   ├── 删除残留图片
   ├── 替换占位符
   └── 记录问题清单给用户
```

---

## 十八、红白风格设计规范 V2.0（2026-04-10整合）

> 基于贾老师PPT深度分析，用于指导红白风格PPT的制作

### 18.1 配色系统

#### 18.1.1 背景色
| 类型 | 颜色 | 用途 |
|------|------|------|
| 红色背景 | #E63946 | 封面上半部分、底部装饰条 |
| 白色背景 | #FFFFFF | 封面下半部分 |
| 浅色背景 | 浅蓝渐变（#F5F7FA 或 #E8F0FA） | 正文页面 |
| 卡片背景 | 白色（#FFFFFF） | 数据卡片、内容块 |

#### 18.1.2 强调色
| 颜色 | 用途 |
|------|------|
| 红色（#E63946） | 标题栏、重点文字、序号、边框 |
| 黄色（#FFD600） | 关键数据、对比标识（VS）、皇冠图标 |
| 蓝色（#1A73E8） | 科技元素、品牌logo、图表柱子 |

#### 18.1.3 文字色
| 颜色 | 用途 |
|------|------|
| 白色（#FFFFFF） | 深色背景上的标题 |
| 黑色（#1A1A2E） | 浅色背景上的正文 |
| 红色（#E63946） | 强调文字、标题 |
| 灰色（#6B7B8D） | 辅助说明文字 |

### 18.2 布局类型

#### 18.2.1 封面页（红白双色分区）
- **布局**：上红下白双色分区
- **红色区域（56%高度）**：
  - 左上角小字：课程归属（白色，14pt）
  - 中间：模块编号（白色，54pt，粗体）
  - 下方：课程主标题（白色，44pt，粗体）
  - 底部：关键词（白色，18pt）
- **白色区域（44%高度）**：
  - 讲师姓名（黑色，36pt，粗体）
  - 公司/职位（灰色，16pt）
- **底部红色装饰条**：高度约0.38英寸
- **文字颜色**：红色区域内白色，白色区域内黑色/灰色

#### 18.2.1b 尾页（红白双色分区）
- **布局**：上红下白双色分区 + 底部红色装饰条
- **红色区域（50%高度）**：
  - "谢谢！"（白色，72pt，粗体，居中）
  - 位置：top≈1500000（红色区域内偏上）
- **白色区域（50%高度）**：
  - 模块标题（黑色，28pt，居中）
  - 位置：top≈4500000（白色区域内）
- **底部红色装饰条**：高度约0.38英寸
- **核心原则**：
  - 两行文字作为整体居中分布
  - "谢谢"在红色背景上（白色）
  - 模块标题在白色背景上（黑色）
  - 两行文字要分开适当距离，避免挤在一起

#### 18.2.2 正文页（红色标题栏）
- **布局**：顶部红色标题栏 + 下方浅色背景，双栏布局
- **红色标题栏**：高度约0.56英寸（822960 EMU），颜色 #E63946
- **标题文字**：白色，28pt，粗体，位于红色标题栏内
- **正文区域**：浅色背景，左右两个白色卡片并排
- **卡片内部元素**：
  - 小标题：黑色，20pt，粗体
  - 红色横线装饰：位于小标题下方，右侧拉长2倍
  - 内容：黑色，20pt，1.5倍行距（line_spacing=1.5），段后间距0
- **核心原则**：
  - 红色标题栏内文字必须为白色
  - 红色横线适当下移，避免与标题重叠
  - 内容文字设置自动换行（word_wrap=True）
  - 文字超出文本框时，缩小字号（18pt）

#### 18.2.3 目录页（卡片式）
- **布局**：顶部红色标题栏 + 下方3个白色卡片水平排列
- **红色标题栏**："目录"（白色，32pt，粗体，左上角）
- **卡片参数**：
  - 卡片数量：3个，左右均匀分布
  - 卡片高度：占内容区域85%，上下居中
  - 卡片样式：白色背景 + 红色边框（1.5pt）
- **卡片内部元素**：
  - 序号：红色方形块（#E63946）+ 白色数字（36pt，粗体，居中）
  - 标题：黑色（20pt，粗体），位于序号下方
  - 红色横线装饰：位于标题下方
  - 内容：灰色（20pt，2倍行距），列点形式
- **核心原则**：
  - 卡片上下居中，不要偏上或偏下
  - 红色横线和内容文字要与标题保持适当距离，避免重叠
  - 字体统一20pt，行距2倍

#### 18.2.4 章节页（左红右白分栏）
- **布局**：左侧红色大色块 + 右侧白色区域
- **红色区域（左侧37.5%宽度）**：
  - 序号：白色，72pt，粗体（如"01"、"02"、"03"）
  - 章节标题：白色，36pt，粗体
  - 位置：左侧整体上下居中
- **白色区域（右侧62.5%宽度）**：
  - "本章要点"：黑色，28pt，粗体
  - 要点内容：黑色，24pt，2倍行距（line_spacing=2.0），段后间距0
  - 位置：右侧整体上下居中
- **核心原则**：
  - 左右两侧内容各自整体居中
  - 序号和标题在红色区域内，白色文字
  - "本章要点"和内容在白色区域内，黑色文字
  - 要点内容行距2倍，段后间距0

#### 18.2.5 卡片式水平排列
- **布局**：2-4个白色卡片水平并排
- **卡片内部**：上文下图 或 上图下文
- **装饰**：白色背景 + 轻微阴影 + 红色边框（重点卡片用蓝色边框）
- **VS对比**：红色"VS"图标分隔对比卡片

#### 18.2.4 左图右文
- **布局**：左侧图片区（50-60%）+ 右侧文字区（40-50%）
- **图片类型**：创意插画、场景照片、数据图表
- **文字层级**：红色标题 → 黑色正文 → 灰色辅助

#### 18.2.5 三段式左图右文
- **布局**：页面分为上中下三段，每段左侧图片 + 右侧文字
- **适用**：介绍3个并列概念/案例
- **特点**：图文一一对应，结构清晰

#### 18.2.6 分块式布局
- **布局**：多个功能区块组合（左/中/右 或 上/中/下）
- **元素**：按钮式色块 + 图标 + 文字框
- **装饰**：红色/黄色色块、大脑图标、VS标识

### 18.3 图文配比规范

| 页面类型 | 图片占比 | 文字占比 | 说明 |
|---------|---------|---------|------|
| 卡片式 | 40-50% | 50-60% | 卡片内图文1:1 |
| 左图右文 | 50-60% | 40-50% | 图片为主 |
| 三段式 | 40-45% | 55-60% | 图文均衡 |
| 数据页 | 10% | 90% | 以表格/文字为主 |
| 流程图 | 60% | 40% | 图片/图标为主 |

### 18.4 字体层级

| 层级 | 字号 | 颜色 | 用途 |
|------|------|------|------|
| 一级 | 48-64pt | 白色/红色 | 页面大标题 |
| 二级 | 28-36pt | 红色/黑色 | 板块标题、卡片标题 |
| 三级 | 20-24pt | 黑色 | 正文要点 |
| 四级 | 14-18pt | 灰色/黑色 | 辅助说明、标签 |
| 五级 | 12pt | 灰色 | 最小补充文字 |

### 18.5 装饰元素

#### 18.5.1 必备元素
- **红色标题栏**：顶部横条（高度约1.2英寸）
- **圆形序号框**：红色填充 + 白色数字
- **圆角矩形卡片**：白色背景 + 红色/蓝色边框
- **VS图标**：红色圆形 + 白色"VS"文字

#### 18.5.2 科技感元素
- **大脑图标**：象征AI/思维
- **齿轮/电路图标**：象征技术
- **箭头流程线**：连接流程步骤
- **皇冠图标**：象征等级/领先

### 18.6 快速应用模板

#### 模板A：卡片式（2卡片对比）
```
[红色标题栏]
[卡片1: 上图下文]  VS  [卡片2: 上图下文]
```

#### 模板B：左图右文
```
[红色标题栏]
[图片区 55%]  [文字区 45%]
```

#### 模板C：三段式
```
[红色标题栏]
[图1 + 文1]
[图2 + 文2]
[图3 + 文3]
```

#### 模板D：分块式
```
[红色标题栏]
[按钮1] [按钮2] [按钮3]
[图表/流程图]
[说明文字]
```

### 18.7 python-pptx实现代码示例

```python
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor

# 颜色定义
class Colors:
    DARK_BLUE_START = RGBColor(0x0A, 0x16, 0x28)  # 深蓝渐变起始
    DARK_BLUE_END = RGBColor(0x1A, 0x3A, 0x5C)    # 深蓝渐变结束
    LIGHT_BLUE = RGBColor(0xF5, 0xF7, 0xFA)       # 浅蓝背景
    RED = RGBColor(0xE6, 0x39, 0x46)               # 红色强调
    YELLOW = RGBColor(0xFF, 0xD6, 0x00)            # 黄色
    BLUE = RGBColor(0x1A, 0x73, 0xE8)              # 蓝色
    WHITE = RGBColor(0xFF, 0xFF, 0xFF)
    BLACK = RGBColor(0x1A, 0x1A, 0x2E)
    GRAY = RGBColor(0x6B, 0x7B, 0x8D)

# 设置渐变背景
def set_slide_background_gradient(slide, color1, color2):
    background = slide.background
    fill = background.fill
    fill.gradient()
    fill._fill.gradient_stops[0].color.rgb = color1
    fill._fill.gradient_stops[1].color.rgb = color2

# 设置纯色背景
def set_slide_background_solid(slide, color):
    background = slide.background
    fill = background.fill
    fill.solid()
    fill.fore_color.rgb = color

# 添加红色标题栏
def add_red_header(slide, title):
    add_shape(slide, Inches(0), Inches(0), Inches(13.33), Inches(0.8), Colors.RED)
    add_text_box(slide, Inches(0.5), Inches(0.1), Inches(12), Inches(0.6),
                 title, 28, Colors.WHITE, True)

# 添加白色圆角卡片
def add_white_card(slide, left, top, width, height):
    return add_rounded_rectangle(slide, left, top, width, height, Colors.WHITE)

# 添加VS对比图标
def add_vs_icon(slide, left, top):
    shape = add_shape(slide, left, top, Inches(1), Inches(1), Colors.RED)
    add_text_box(slide, left, top + 0.15, Inches(1), Inches(0.7),
                 "VS", 28, Colors.WHITE, True, PP_ALIGN.CENTER)
```

---

**版本**: V2.0（整合版）  
**更新日期**: 2026-04-10  
**来源**: 红白风格设计规范V2.0 + ppt-pandora实战经验

---

## 十九、实战案例：模块四AGV路径规划PPT（2026-04-10）

### 19.1 项目背景
- **主题**：工业互联网赛项培训课程 - 模块四：AGV路径规划
- **课时**：3课时（135分钟）
- **风格**：红白风格（白色背景版）
- **最终成果**：17页PPT，文字内容充实，章节页有设计感

### 19.2 制作过程与经验教训

#### ❌ 失败尝试（V0-V1）
**问题1：模板文件选错**
- 错误：使用了已填充内容的PPT（`大模型讲座1_红白风格V3_阿里普惠体.pptx`）作为模板
- 后果：旧内容清不干净，背景样式混乱
- **教训**：必须使用纯净模板（`模板与规范/模板.pptx`）

**问题2：python-pptx无法实现复杂视觉效果**
- 尝试：用代码实现渐变背景、圆角卡片、彩色图标
- 后果：效果差，与设计规范差距大
- **教训**：python-pptx适合简单布局，复杂视觉效果需要其他方案

**问题3：章节页没有设计感**
- 错误：章节页只是简单的深色背景+白色文字
- 后果：贾老师评价"章页很丑，没有设计"
- **教训**：章节页需要强视觉冲击力

**问题4：页面太空，文字太少**
- 错误：每页只有几个要点，内容单薄
- 后果：贾老师评价"所有页面都太空，文字内容太少"
- **教训**：课程PPT可以不加图片，但文字要充实

#### ✅ 成功方案（V2）
**解决方案1：白色背景**
- 做法：放弃深蓝渐变，全页面白色背景
- 效果：简洁干净，符合贾老师要求

**解决方案2：章节页重新设计**
- 做法：左侧大红色色块 + 超大白色章节编号 + 右侧本章要点
- 代码示例：
```python
def create_section(prs, num, title, subtitle, key_points):
    # 左侧大红色色块
    add_shape(slide, Inches(0), Inches(0), Inches(5), Inches(7.5), C.RED)
    # 章节编号（超大白色数字）
    add_text(slide, Inches(0.3), Inches(0.8), Inches(4.4), Inches(2),
             num, 120, C.WHITE, True, PP_ALIGN.CENTER)
    # 右侧白色区域 - 本章要点
    add_text(slide, Inches(5.5), Inches(0.8), Inches(7.5), Inches(0.6),
             "本章要点", 28, C.RED, True)
```

**解决方案3：从脚本提取详细文字**
- 做法：将教学脚本中的详细讲解内容直接放入PPT
- 效果：每页文字量增加3-4倍，内容充实
- 布局：双栏/三栏布局，避免单栏过长

**解决方案4：内容页布局优化**
- 双栏布局：两个白色卡片并排，每个卡片有红色小标题+详细文字
- 三栏布局：三个白色卡片并排，适合对比类内容
- 代码示例：
```python
def create_content(prs, title, sections):
    if num_sections == 2:
        for i, (section_title, lines) in enumerate(sections):
            x = 0.5 + i * 6.5
            card = add_rounded(slide, Inches(x), Inches(1.2), Inches(6), Inches(5.8), C.WHITE)
            add_text(slide, Inches(x + 0.3), Inches(1.4), Inches(5.4), Inches(0.5),
                     section_title, 20, C.RED, True)
```

### 19.3 最终PPT结构（17页）

| 页码 | 内容 | 布局特点 |
|------|------|----------|
| P1 | 封面 | 上红下白，红色大色块+白色标题 |
| P2 | 目录 | 红色标题栏+三个竖排章节卡片 |
| P3 | 章节页01 | 左红右白，超大编号"01"+本章要点 |
| P4 | AGV定义 | 双栏：AGV定义+核心特征 |
| P5-6 | 发展历程 | 双栏：每代详细说明 |
| P7 | 导航对比 | 四栏：磁/激光/视觉/SLAM |
| P8 | 章节页02 | 左红右白，超大编号"02" |
| P9-11 | 算法详解 | 双栏：原理+应用+优缺点 |
| P12 | 章节页03 | 左红右白，超大编号"03" |
| P13-15 | 应用案例 | 双栏/三栏：背景+架构+效果 |
| P16 | 总结 | 三列彩色卡片 |
| P17 | 结束页 | 上红下白，红色"谢谢" |

### 19.4 关键设计规范

**颜色**
- 背景：白色（#FFFFFF）
- 标题栏：红色（#E63946）
- 强调：黄色（#FFD600）
- 正文：黑色（#1A1A2E）
- 辅助：灰色（#6B7B8D）

**字体**
- 章节编号：120pt，白色，粗体
- 小标题：20pt，红色，粗体
- 正文：15-16pt，黑色
- 辅助文字：14pt，黑色

**布局原则**
- 卡片间距：0.3-0.5英寸
- 卡片内边距：0.2-0.3英寸

### 19.5 贾老师的反馈记录

> "这个就很好了。务必记住这个ppt诞生的过程，计入ppt pandora"

**关键反馈点**：
1. ✅ 章节页设计感强（左侧红色大色块+超大编号）
2. ✅ 文字内容充实（从脚本提取详细讲解）
3. ✅ 白色背景简洁干净
4. ❌ 之前版本：章节页丑、页面太空

---

**案例记录日期**：2026-04-10  
**设计师**：喵小屁 🐱💨  
**审核人**：贾老师

---

## 二十、实战案例：模块一PLC编程PPT（2026-04-10）

### 20.1 项目背景
- **主题**：工业互联网赛项培训课程 - 模块一：PLC编程与自动化产线控制
- **总课时**：4课时（有实操内容）
- **PPT理论课时**：2课时（90分钟）
- **最终版本**：V4（25页）

### 20.2 课时评估流程（重要）

#### 评估规则
1. **确定模块总课时**（按4天完整版，不是2天精简版）
2. **检查青椒是否有实操内容**
3. **分配课时**：
   - 有实操 → PPT理论占一半，实操占一半
   - 无实操 → PPT理论占全部课时

#### 模块一评估结果
| 项目 | 数值 |
|------|------|
| 总课时 | 4课时 |
| 青椒实操 | 有（OpenPLC编程、Flask Web） |
| PPT课时 | 2课时（90分钟） |

### 20.3 页面数量与课时匹配

#### 经验公式
- **课程PPT**：每页约3-4分钟讲解时间
- **90分钟** → 约25-30页
- **45分钟** → 约12-15页

#### V3 vs V4对比
| 版本 | 页数 | 每页时间 | 问题 |
|------|------|---------|------|
| V3 | 15页 | 6分钟/页 | 太少，撑不满90分钟 |
| V4 | 25页 | 3.6分钟/页 | ✅ 适中 |

### 20.4 内容密度优化

#### 问题发现
- V2：页面太空，只用了一半空间
- V3：字号太小（10-12pt），内容过于密集

#### 解决方案
1. **调整字号**：正文11-12pt，标题16-18pt
2. **合理布局**：单栏/双栏/三栏根据内容选择
3. **充分利用空间**：卡片高度增加到6英寸

#### 字号规范（课程PPT）
| 元素 | 字号 |
|------|------|
| 页面标题 | 28pt |
| 小标题 | 16-18pt |
| 正文 | 11-12pt |
| 辅助文字 | 10pt |

### 20.5 布局选择原则

#### 布局类型与适用场景
| 布局 | 适用场景 | 示例 |
|------|---------|------|
| 单栏 | 详细讲解、原理说明 | PLC定义、工作原理 |
| 双栏 | 对比、并列内容 | 硬件组成、定时器/计数器 |
| 三栏 | 三个并列要点 | 逻辑指令、课程总结 |
| 表格 | 数据对比 | PLC品牌、地址映射 |

#### 避免的问题
- ❌ 每页都用同一种布局（太死板）
- ❌ 内容太少导致页面太空
- ❌ 内容太多导致文字超出

### 20.6 制作经验总结

#### 关键教训
1. **先评估课时** → 确定页面数量
2. **内容密度适中** → 不能太空也不能太密
3. **布局多样化** → 根据内容选择布局
4. **字号适中** → 11-12pt适合课程PPT

#### 模型选择
- **文字处理**：使用mimo-v2-pro
- **图片识别**：切换到mimo-v2-omni

---

**案例记录日期**：2026-04-10  
**设计师**：喵小屁 🐱💨


path: _meta.json
content: slug: ppt-pandora
version: 1.0.0

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)