gpt-image2-ppt
gpt-image2-ppt -- 用 gpt-image-2 生成 PPT
把一份 markdown 大纲(或 slides_plan.json)+ 一种视觉风格,直接喂给 OpenAI 官方 Images API(gpt-image-2),逐页出图,最后拼成一个键盘可翻页的 HTML viewer + 16:9 .pptx。
十种内置风格
| 风格 ID | 一句话定位 | 适用场景 |
|---|---|---|
gradient-glass |
Apple Vision OS / Spatial Glass | AI 产品发布、技术分享、创意提案 |
clean-tech-blue |
Stripe / Linear 级蓝白 | 融资路演、商业计划书、企业战略 |
vector-illustration |
复古矢量插画 + 黑描边 | 教育培训、品牌故事、社区分享 |
editorial-mono |
Kinfolk / Monocle 编辑设计 | 品牌发布、文化访谈、读书分享 |
dark-aurora |
Linear / Vercel 深色霓虹 | AI 产品、开发者工具、技术分享 |
risograph |
Riso 双套色印刷 + 网点纹理 | 创意工作室、文创品牌、独立 zine |
japanese-wabi |
无印 / 原研哉式侘寂 | 茶道、生活方式、奢侈品、文化讲座 |
swiss-grid |
Bauhaus / Vignelli 国际主义网格 | 学术报告、博物馆展陈、严肃汇报 |
hand-sketch |
Sketchnote / 白板手绘 | 工作坊、产品 brainstorming、培训 |
y2k-chrome |
Y2K 千禧液态金属 + 蝴蝶贴纸 | 潮牌、文娱、品牌联名、Z 世代营销 |
风格选择原则:技术类首选
dark-aurora/gradient-glass,商务类首选clean-tech-blue/editorial-mono,文化生活类首选japanese-wabi/vector-illustration,潮文娱类首选risograph/y2k-chrome,学术类首选swiss-grid,工作坊与早期创意类首选hand-sketch。
模板克隆模式
直接给 skill 一个 .pptx 模板,后续所有页都仿这个模板。
# 一行:自动渲染 + vision 抽风格 + 出图。本机有 LibreOffice 或 docker 镜像即可
python3 scripts/generate_ppt.py \
--plan slides_plan.json \
--template-pptx ./company-template.pptx \
--template-strict
--template-strict 表示每页都把模板对应页作为 image reference 喂给 gpt-image-2,仿真度最高。
模板渲染:本机不需要操作 PowerPoint
skill 自带 render_template.py,把 .pptx 自动渲染成每页 PNG,存到 <cwd>/template_renders/<stem>/page-NN.png。
后端按优先级自动挑:
- 本机
libreoffice/soffice命令(最快) - 本机 docker +
linuxserver/libreoffice镜像(首次拉 ~2.5GB) - PDF -> PNG 走
pymupdf(已在 requirements);没装就用pdf2image+ poppler
如果两种 LibreOffice 都没有,会让用户手动从 PowerPoint/Keynote/WPS 导出每页 PNG,命名 page-01.png 起按字典序对应页码。
跑 generate_ppt.py --template-pptx ... 时如果省略 --template-images 会自动调一次渲染;也可以手动先跑一次:
python3 scripts/render_template.py company-template.pptx
# -> <cwd>/template_renders/company_template/page-01.png ... page-NN.png
仿模板的两层缓存
| 资料 | 路径 | 用途 |
|---|---|---|
| 模板每页 PNG | <cwd>/template_renders/<stem>/page-NN.png |
LibreOffice 一次渲染长期复用 |
| Vision 风格分析 | <cwd>/template_cache/<sha256>.json |
gemini-3.1-pro-preview 一次分析长期复用 |
| 生成产物 | <cwd>/outputs/<timestamp>/ |
每次新跑都新目录 |
三者都在调用者 cwd 下,与项目自然同进退;建议把 template_renders/、template_cache/、outputs/ 加进项目的 .gitignore。
vision 模型(让 agent 自己判断要不要配):
- 如果当前运行本 skill 的 agent 自己就是多模态的(Claude Code 走 Claude Opus/Sonnet 等多模态 SKU、codex 走 GPT 多模态 SKU 等),压根不用外挂 vision 模型:直接让 agent 自己
Readtemplate_renders/<stem>/page-*.png,一次把风格抽出来写进template_cache/<sha256>.json即可(schema 见template_analyzer.py)。这是默认路径,不需要配VISION_*。 - 只有 agent 本身是纯文本模型(或你想强制用某个更强的 vision 做模板分析),才去配
VISION_*让template_analyzer.py走一个独立的 OpenAI 兼容多模态 chat completions 端点(Gemini / GPT / Claude 任选,不内置 default)。
vision 分析与图片生成的 gpt-image-2 永远解耦——换 vision provider 不影响出图路径。
安装
git clone git@github.com:JuneYaooo/gpt-image2-ppt-skills.git
cd gpt-image2-ppt-skills
bash install_as_skill.sh --target claude # Claude Code
# 或
bash install_as_skill.sh --target codex # Codex
# 仅当你走 API 直连模式时,再编辑对应目录下的 .env 填入 API_KEY
必需的环境变量
OPENAI_BASE_URL=https://api.openai.com # 或任意 OpenAI 兼容中转站
OPENAI_API_KEY=sk-...
GPT_IMAGE_MODEL_NAME=gpt-image-2
GPT_IMAGE_QUALITY=high # low / medium / high / auto
# 可选:模板克隆模式的 vision 分析 backend。
# 默认让调用本 skill 的 agent 自己看图(多模态 Claude Code / 多模态 codex 皆可),
# 只有 agent 本身是纯文本模型时才需要外挂下面这组。
# 不内置默认 endpoint,请填你自己信任的服务,否则就别填。
# VISION_BASE_URL=https://your-openai-compatible-relay.example.com/v1
# VISION_API_KEY=sk-...
# VISION_MODEL_NAME=gemini-3.1-pro-preview # 或 gpt-4o / claude-3.5-sonnet 等任意多模态 SKU
安全提示:脚本只从
<script_dir>/.env、~/.codex/skills/.../.env、~/.claude/skills/.../.env、~/skills/.../.env与显式GPT_IMAGE2_PPT_ENV加载凭据,不会向上递归读取项目目录里的.env,避免误吃无关密钥。
如果你就是 Codex agent(原生 image_generation 出图 — 推荐)
如果你自己就是 Codex(正在运行本 skill 的 agent 就是 Codex CLI / Codex TUI),你自带 image_generation tool 和 ChatGPT 登录态。此时不要跑 generate_ppt.py,直接用原生工具完成整个 pipeline——零依赖、零 API Key、零套娃。
如何判断
你能访问 image_generation tool,并且不需要手动配 OPENAI_API_KEY 就能出图——满足这两个条件就走原生路径。
出图流程(Codex 原生路径)
1. 准备 slides 数据
如果还没有 slides_plan.json,先按下面「生成流程」第 2-3 步写 slides_plan.md → python3 scripts/md_to_plan.py ... 转 json。
2. 读风格模板
读 styles/<id>.md,取 ## 基础提示词模板 section 作为 base prompt。
3. 构造每页 prompt
参考 generate_ppt.py 的 generate_prompt() 逻辑,核心规则:
- 封面(cover/slide 1):标题/副标题为视觉焦点
- 数据页(data/最后一页):突出关键数字、对比或结论
- 内容页(content/其余页):按层级、对齐、留白结构化呈现
- 所有文字必须简体中文,字体用思源黑体/苹方,严禁草书/艺术字
- 16:9 横版宽屏(landscape, widescreen),prompt 里明确说"宽度明显大于高度、绝对不要方图"
{style 基础提示词模板}
---
现在请生成本组中的【{封面页/内容页/数据页}】,{对应 hint}
本页要呈现的内容如下(请按本风格美学重新设计版式):
{slide content}
【强制语言与字体要求】
1. 所有文字必须使用简体中文,严禁英文(专有名词除外)
2. 中文字体使用思源黑体或苹方,严禁草书、艺术字
3. 标题粗体,正文常规,字号对比清晰
【画面比例 — 强制】16:9 横版宽屏 (landscape, widescreen),宽度明显大于高度,绝对不要方图或竖图。
4. 调 image_generation tool 出图
对每页调你的 image_generation tool:
prompt: 上面拼好的完整 promptoutput_format:png- 将返回的图片保存到
outputs/<timestamp>/images/slide-NN.png(NN 为两位页码)
可以并发(建议 ≤4 并发,避免限流)。
5. 生成 HTML viewer
读 templates/viewer.html,把 /* IMAGE_LIST_PLACEHOLDER */ 替换为 'images/slide-01.png', 'images/slide-02.png', ...,写到 outputs/<timestamp>/index.html。
6. 打包 PPTX(可选)
python3 -c "
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
import os, glob
for p in sorted(glob.glob('outputs/<timestamp>/images/slide-*.png')):
slide = prs.slides.add_slide(blank)
slide.shapes.add_picture(p, 0, 0, width=prs.slide_width, height=prs.slide_height)
prs.save('outputs/<timestamp>/<title>.pptx')
print('done')
"
模板克隆模式(Codex 原生路径)
你自己就是多模态 agent——直接 Read 模板每页 PNG 抽取视觉风格,写到 template_cache/<sha256>.json(schema 见 template_analyzer.py 里的 TemplateProfile),然后按上面流程出图时把对应模板页作为 reference image 传给 image_generation tool。
不需要配 VISION_*——你就是 vision。
与下面「--backend codex」的区别
| 原生路径(本节) | --backend codex | |
|---|---|---|
| 适用场景 | 你就是 Codex agent | 你是 Claude Code / 其他 agent,借用本机 codex CLI |
| 调用方式 | 直接调 image_generation tool |
spawn codex exec --full-auto 子进程 |
| 出图层数 | 1 层 | 2 层(agent → python → codex exec) |
| 速度 | 几秒/张 | 30-60s/张 |
| 可靠性 | tool 参数精确 | 自然语言 relay,偶发失败 |
| 需要 API Key | 不需要 | 不需要 |
可选:走 codex CLI 出图(--backend codex,非 Codex caller 用)
如果你就是 Codex agent,不要走这条路——用上一节的「原生路径」代替。
当你用 Claude Code / OpenClaw / 其他 agent 运行本 skill,但本机装了 codex CLI 且已登录(codex login),可以借用它的凭据出图,省掉配 OPENAI_API_KEY:
python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/editorial-mono.md --backend codex
默认后端仍是 openai(直调 API,快、并发稳、每页 3-10s)。--backend codex 是逃生口,适合"只跑 1-2 张图试水、不想配 key"的场景。
Tradeoffs:
- ✅ 不需要在本 skill 配
OPENAI_API_KEY - ⚠️ 慢:每页多一层 agent loop,单页 30-60s+,10 页可能 5-10 分钟
- ⚠️ 计费不变:gpt-image-2 是按图计费,不在 ChatGPT 订阅内,codex 只是代你刷额度
- ⚠️ 可控性差:aspect_ratio / quality / reference_image 靠自然语言指令让 codex 转发,偶发失败
相关 env(都可选):
CODEX_CMD="codex exec --full-auto" # 覆盖 codex 调用方式(默认这串)
CODEX_IMAGE_MODEL=gpt-image-2 # 传给 codex 的目标模型
CODEX_TIMEOUT_SECS=900 # 单页超时
GPT_IMAGE_BACKEND=codex # 不想每次敲 --backend 就设这个
模板克隆的 vision 分析同理——当 caller agent 自己是多模态时(Claude Code / 多模态 codex),可以直接 Read 模板 PNG 抽取风格,不用配 VISION_*;只有 caller agent 是纯文本模型时才需要外挂 vision provider。
生成流程(内置风格)
先 md 后 json:md 给人看、方便 diff / review / 改文案;json 由 md 派生,喂给 generate_ppt.py,标为 generated,不手改。
- 用户给一份大纲 / 已有的 slides_plan.json
- Claude 按下面 md 规范写一份
slides_plan.md,与用户确认文案:--- title: MediWise Health Suite 商业计划书 --- ## 1. [cover] MediWise Health Suite 副标题:家庭健康管理智能平台 年份:2026 ## 2. [content] 市场痛点:健康管理的两类割裂 痛点一:高频无深度 ... ## 6. [data] 效率对比:使用 MediWise 前后 ...- h2 格式:
## N. [page_type, layout=layout-05] 本页标题行 N.可省(按出现顺序自动编号);[page_type]可省(默认content);layout=只在模板克隆模式需要page_type:cover/content/data- h2 标题行 → json 里
content的第一行;下面的正文 → 正文
- h2 格式:
- 用户 OK 后,转 json:
python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json - 选风格:从上面 10 套里挑一个,对应
styles/<id>.md - 调脚本:
python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/editorial-mono.md - 产物在
<cwd>/outputs/<timestamp>/:images/slide-XX.png-- 每页 PNG(16:9,1536x1024)index.html-- HTML viewer,方向键翻页、空格自动播放、ESC 全屏prompts.json-- 每页用到的完整 prompt(便于复盘 / 二次微调)<title>.pptx-- 16:9 整页填充图片的 .pptx,分享 / 投影直接用
生成流程(模板克隆)
- 拿到模板 .pptx(用户提供 / 内部模板库 / 网络下载)
- (可选)先单独渲染并人工挑选----大模板(>15 页)建议先
python3 scripts/render_template.py xxx.pptx,再从template_renders/<stem>/里挑 8-12 张代表页复制到template_renders/<stem>_curated/,供 vision 分析。页数越精,layout 命中越准 - 生成 slides_plan.md → 转 slides_plan.json(见内置风格流程第 2-3 步)。每页
slide_number/page_type(cover/content/data/ 等) /content;想精准对位时在 h2 里加layout=layout-NN(NN = 模板第 N 页 / 你期望对应的模板页编号) - 跑 generate_ppt.py:
先python3 scripts/generate_ppt.py \ --plan slides_plan.json \ --template-pptx xxx.pptx \ --template-images template_renders/xxx_curated \ --template-strict --slides 1--slides 1出封面冒烟,效果 OK 再跑全量 - 告知用户产物路径
模板页面挑选 / 复用原则
核心原则:尽量做到 1 page : 1 layout----同一份 deck 里每个 slide 用不同的模板页作 reference,观众会觉得每页都是新内容;如果同一个独特 layout 出现 2-3 次,观众下意识会想"为什么又是这页"。
vision 分析时会给每个 layout 标 reuse_friendly:
| reuse_friendly | 典型 layout | 多次使用的代价 |
|---|---|---|
false(不可复用,(!) 强警告) |
封面、3 个具名角色插画页、独特场景图(雪山/广播塔/复古收音机)、5 步骤 zigzag 各步独有图标、novelty 数据中央装置 | 视觉重复非常明显,观众会困惑 |
true(可复用,但仍建议错开,(i) 弱提示) |
纯文字、卡片网格、通用列表、章节小节标题 | 不致命,但平白浪费模板里的其它好版式 |
Claude 在搭 plan 时的执行策略:
- 优先把模板里 N 个不同 layout 分配给 N 页 slide(N 不够就在 SKILL 里看 reuse_friendly=true 的部分挑能复用的)
- 如果 plan 里某页内容结构非常相似(比如多个"5 步骤流程"),先尝试改写内容用不同 layout 表达(4 步骤 + 5 步骤分别用不同流程页),而不是同一个 zigzag 用两次
- 冒烟跑完后,看
Layout 复用检测那段输出:(!) 必须改,(i) 看情况改;改 plan 里相应 slide 的layout_id即可 - 看完 cache JSON 选 layout:
cat <cwd>/template_cache/<sha256>.json | jq '.layouts[] | {id, page_type, reuse_friendly, summary}'一眼看清模板有哪些版式可挑
generate_ppt.py 在派发任务前会自动跑一次复用检测,把警告打到终端,不阻塞执行。
Skill 调用规范
当用户说"做一份 PPT" / "生成幻灯片"时:
- 先问三件事(不要直接动手):
- 内容 / 页数 / 观众是谁?
- 风格偏好?按"十种内置风格"表的场景类目映射推荐 1-2 个;或者用户上传自己的 .pptx 模板(走
--template-pptx,自动渲染) - 是否需要单页测试一张图先看效果(
--slides 1)
- 先写 slides_plan.md 给用户确认文案(md 是 source of truth,人审阅友好)
- 转 slides_plan.json:
python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json(json 标为 generated,不手改;要改文案回到 md 改再转) - 跑 generate_ppt.py,先
--slides 1出封面冒烟,效果 OK 再跑全量 - 告知用户产物路径,让他在浏览器打开
outputs/<timestamp>/index.html或者<title>.pptx
仅生成部分页
python3 scripts/generate_ppt.py --plan my_plan.json --style styles/dark-aurora.md --slides 1,3,5
跑过的页有同名 PNG 时会自动跳过,方便逐页迭代。
文件结构
gpt-image2-ppt-skills/
|---- SKILL.md # 本文件(Claude Code skill 入口)
|---- AGENTS.md # codex / aider / cursor 等 agent 的薄索引,指向本文件
|---- README.md # 项目说明
|---- scripts/ # 所有 Python 脚本
| |---- generate_ppt.py # 主入口(CLI)
| |---- md_to_plan.py # slides_plan.md -> slides_plan.json 转换器(CLI)
| |---- render_template.py # PPTX -> 每页 PNG 的辅助脚本(CLI + library)
| |---- image_generator.py # gpt-image-2 wrapper(支持 reference image,openai backend)
| |---- codex_backend.py # 可选:走 codex CLI 出图(--backend codex)
| \---- template_analyzer.py # PPT 模板剖析器(vision + 缓存)
|---- styles/ # 10 套内置风格
| |---- gradient-glass.md dark-aurora.md
| |---- clean-tech-blue.md risograph.md
| |---- vector-illustration.md japanese-wabi.md
| |---- editorial-mono.md swiss-grid.md
| |---- hand-sketch.md y2k-chrome.md
|---- templates/viewer.html # HTML viewer 模板
|---- docs/README.en.md # 英文 README
|---- install_as_skill.sh # 一键安装到 ~/.claude/skills/
|---- requirements.txt # requests + python-dotenv + python-pptx + jsonschema + pymupdf
\---- .env.example
调用时产生的运行时目录都在 <cwd> 下:
<your-project>/
|---- template_renders/<stem>/page-NN.png # PPTX 渲染(render_template.py)
|---- template_cache/<sha256>.json # vision 风格分析缓存
\---- outputs/<timestamp>/ # 每次生成产物
License
Apache License 2.0.
More from ninehills/skills
file-manager
Find, organize, and manage files on the user's computer. Search by name, type, size, or date. Move, rename, compress, and clean up files.
125self-reflection
Daily self-reflection and personal growth. Triggered by heartbeat at end of day. Review the day's experiences, extract lessons, update personality, and write a diary entry.
124send-file
Send files, photos, audio, or videos to the current chat. MUST use whenever you need to deliver any file to the user. Covers: sending images, selfies, generated art, documents, music, videos, voice messages, screenshots, or ANY file the user asks to see. Triggers: 'send it to me', 'send it over', 'let me see', 'send me', 'show me', 'send photo', 'send file', sharing any file path. NEVER paste raw file paths in text — ALWAYS use this skill to send files.
117tvscreener
Query TradingView screener data for HK, A-share, A-share ETF, and US symbols with deepentropy/tvscreener. Use for stock lookup, technical indicators (price/change/RSI/MACD/volume), symbol filtering, and custom field/filter-based market queries.
65screenshot
Take screenshots of the screen using macOS screencapture. Use when users ask to see the screen, debug UI, or capture what's displayed. Resize before returning to avoid blowing up model context.
38agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction.
36