游乐游手机版
首页/AI教程/文章详情

从零开始用Codex搭建脚本分镜图片生成器教程

时间:2026-07-11 14:31
基于Flask与原生JavaScript,构建了一个分镜图片生成器。后端调用异步图像生成API,通过轮询获取任务结果并下载至本地保存。前端支持多输入框管理提示词,提供依次或并行生成模式。不上前端框架,简化部署,解决了分镜制作中沟通成本高、效率低的问题。

零、效果图

一、为什么做这个工具

做短视频、做动画、做漫画脚本的人,几乎都绕不开一个环节——分镜。

传统流程是:编剧写好脚本 → 画师根据文字描述画出每一镜的画面 → 反复修改。这个过程慢、贵、且沟通成本高。

于是,一个很自然的想法就冒出来了:能不能让 AI 直接根据每一句分镜描述生成图片?

答案是肯定的。现在的图像生成模型(GPT-Image-2、豆包 Seedream 系列)已经能根据文字描述生成相当可用的画面。要做的,就是把“输入文字 → 出图 → 保存”这个流程封装成一个简单好用的 Web 工具。

二、需求是怎么一步步清晰的

刚开始的想法很朴素:“调用 OpenAI 的画图 API,输入提示词,出图保存”。

但真正动手前,和 AI 助手做了一轮 brainstorming,把需求一点点抠清楚。这个过程很重要,模糊的需求一定会导致返工。

第 1 轮:交互形态

选择了 Web 页面。理由很简单:分镜创作是个视觉活,命令行黑框框看着没感觉,Web 页面能直接预览图片、能下载、能反复调整。

第 2 轮:技术栈

选了纯 HTML + 原生 Ja vaScript。不引任何前端框架。为什么?因为这个工具逻辑极简——一个输入框、一个按钮、一张图。上 React 纯属杀鸡用牛刀,反而增加构建复杂度。原生 JS 一个 IIFE 就搞定了。

后端用 Flask。Python 生态对 API 调用友好,Flask 又是最轻量的 Web 框架,单文件就能跑。

第 3 轮:API Key 怎么管

最初选了页面输入(方便演示),但很快意识到这有安全隐患。最后改成 .env 配置文件 + python-dotenv 自动加载。.env.gitignore 排除,密钥永不进版本库。这是更工程化的做法。

第 4 轮:用哪个模型

这是关键转折点。一开始说“调 OpenAI 的画图 API”,但实际想用的是 gpt-image-2、gpt-image-2-vip、gpt-image-2-high 和 doubao-seedream-4-0/4-5/5-0 这几个模型。

这些模型并非 OpenAI 官方直出,而是通过一个第三方袋里服务提供的(兼容 OpenAI 接口格式)。这一步确认后,后面所有 API 调用逻辑都围绕第三方的文档来写。

第 5 轮:要不要做视频

豆包 Seedream 系列其实也能生成视频。但果断说只做图片。

理由:视频生成耗时长(分钟级)、文件大、还要轮询任务状态,复杂度比图片高一个数量级。YAGNI(You Ain't Gonna Need It)——先把图片做稳,视频以后再说。这个决策让整个项目复杂度降了一个档。

三、读懂 API 文档:从同步到异步的踩坑

这是整个项目最关键的技术转折。

最初按 OpenAI 标准接口写代码:

resp = requests.post(f"{API_BASE_URL}/v1/images/generations", json=payload, headers=headers)result = resp.json()image_url = result["data"][0]["url"]# 直接拿图

结果发现——ToAPIs 的图像生成是异步的!

打开文生图官方文档,返回值长这样:

{"id": "task_img_abc123def456","object": "generation.task","model": "gpt-image-2","status": "queued","progress": 0,"created_at": 1703884800}

注意:第一次请求只返回 task_id 和状态,不返回图片!你得拿着 task_id 去另一个接口轮询:

GET /v1/images/generations/{task_id}

直到 status 变成 completed,才能在 result.data[0].url 拿到真正的图片地址。

文档里还贴心地给了轮询策略建议:

初始等待: 2 秒轮询间隔: 3 秒最大等待: 120 秒典型耗时: 5-30 秒

还有一个坑:生成的图片 URL 有效期只有 24 小时。所以必须在拿到 URL 后立刻下载到本地,不能只存 URL。

于是后端逻辑变成了三步走:

  1. 提交任务 → 拿 task_id
  2. 轮询状态 → 每 3 秒查一次,最多 40 次(约 120 秒)
  3. 下载图片 → 保存到 ./images/,返回本地 URL 给前端

# 提交任务resp = requests.post(f"{API_BASE_URL}/v1/images/generations", json=payload, headers=headers, timeout=30)task_id = resp.json().get("id")# 轮询for attempt in range(40):time.sleep(3)status_resp = requests.get(f"{API_BASE_URL}/v1/images/generations/{task_id}", headers=headers, timeout=30)status_data = status_resp.json()if status_data.get("status") == "completed":image_url = status_data["result"]["data"][0]["url"]# 下载并保存img_resp = requests.get(image_url, timeout=30)filename = f"image_{int(time.time())}_{os.urandom(4).hex()}.png"with open(os.path.join(IMAGES_DIR, filename), "wb") as f:f.write(img_resp.content)return jsonify({"image_url": f"/images/{filename}"})elif status_data.get("status") == "failed":return jsonify({"error": "图片生成失败"}), 500

另外还有一个模型差异细节:Seedream 系列的分辨率参数要走 metadata.resolution,而 GPT-Image-2 系列直接用 resolution 顶层字段。后端要根据 model 名字判断走哪条路:

if model.startswith("doubao-seedream") and resolution:payload["metadata"] = {"resolution": resolution}

这种“看文档才发现的细节”,是远程 API 集成最耗时的部分。没有捷径,就是读文档 + 试错。

四、前端:从单输入框到多输入框的演进

第一版前端就一个 textarea,用户把所有分镜塞进去,用换行分隔。简单,但不好用:

  • 想删中间某一条得手动挪光标
  • 看不清自己一共写了几条
  • 没法对单条单独操作

于是改成动态多输入框:

  • 默认一个输入框
  • 点「+ 添加提示词」按钮新增一个
  • 每个输入框右上角有「删除」按钮
  • 聚焦时才显示删除按钮,避免界面杂乱

核心就是一段 DOM 操作:

function addPromptGroup(promptText) {var group = document.createElement("div");group.className = "prompt-group";var textarea = document.createElement("textarea");textarea.className = "promptInput";// ...var removeBtn = document.createElement("button");removeBtn.textContent = "删除";removeBtn.addEventListener("click", function() {group.remove();});group.appendChild(textarea);group.appendChild(removeBtn);promptsContainer.appendChild(group);}

收集所有提示词时遍历一遍:

function getPrompts() {var inputs = promptsContainer.querySelectorAll(".promptInput");var prompts = [];for (var i = 0; i < inputs.length; i++) {var val = inputs[i].value.trim();if (val.length > 0) prompts.push(val);}return prompts;}

五、依次生成 vs 并行生成:两种模式的设计

分镜往往一画就是十几张。如果一张一张串行生成,10 张图每张 20 秒就要等 3 分钟。如果并行,理论上 20 秒就能全拿回来。

所以加了「处理模式」下拉框:

依次生成(sequential)

for (var i = 0; i < prompts.length; i++) {var img = await generateOne(prompts[i], model, size, resolution);appendResult({ prompt: prompts[i], url: img.image_url, index: i });}

特点:一张完成才生成下一张。好处是省 API 配额、出错好定位、前端能看到逐张出现的过程。坏处是慢。

并行生成(parallel)

var tasks = prompts.map(function(p, i) {return generateOne(p, model, size, resolution).then(function(img) {appendResult({ prompt: p, url: img.image_url, index: i });}).catch(function(err) {appendResult({ prompt: p, error: err.message, index: i });});});await Promise.all(tasks);

特点:所有任务同时发出,谁先回来谁先显示。快,但要注意限流(429 错误)。如果配额吃紧,建议用依次模式。

两种模式都用 try/catch 包裹单张生成,一张失败不影响其他张——这对分镜这种“批量但单张独立”的场景很重要。

六、那些调试中的小坑

坑 1:点击生成按钮没反应

部署完第一次点按钮,毫无响应。打开浏览器控制台,发现:

GET https://127.0.0.1:5000/script.js 404 (NOT FOUND)

原因:Flask 默认静态文件目录是 static/,访问路径必须是 /static/script.js,不是 /script.js。改一行:

<script src="script.js">script><script src="/static/script.js">script>

坑 2:API_BASE_URL 写成了完整路径

.env 里一开始写了:

API_BASE_URL=https://xxxxx.com/v1/images/generations

app.py 里又拼了一遍 /v1/images/generations,导致最终 URL 变成:

https://xxxx.com/v1/images/generations/v1/images/generations

404。改成只写根域名:

API_BASE_URL=https://xxxxx.com

配置项只放根地址,路径在代码里拼——这是惯例,避免重复。

坑 3:pip 命令找不到

PowerShell 里直接敲 pip install 报 “无法识别”。原因是没激活虚拟环境,且系统 Python 没把 pip 加进 PATH。

解法是用 py -m pip 或激活虚拟环境后用 python -m pip

venvScriptsActivate.ps1pip install -r requirements.txt

七、最终项目结构

画图程序/├── app.py# Flask 后端:异步任务 + 轮询 + 本地保存├── static/│ ├── index.html# 前端:多输入框 + 参数选择 + 结果展示│ └── script.js # 前端逻辑:多输入框管理、依次/并行生成├── .env# 配置:API_KEY + API_BASE_URL(不提交)├── .env.example# 配置模板├── requirements.txt# flask / requests / python-dotenv├── .gitignore# 排除 .env / images/ / venv/├── README.md # 使用文档├── venv/ # 虚拟环境└── images/ # 运行时生成图片存放

启动:

cd "D:Usersopencode画图程序"venvScriptsActivate.ps1python app.py

浏览器打开 https://127.0.0.1:5000,界面长这样:

  • 顶部一个提示词输入框(可点「+ 添加提示词」新增)
  • 模型下拉框(6 个模型可选)
  • 宽高比下拉框(1:1 / 4:3 / 16:9 / 9:16 / 21:9 等)
  • 分辨率下拉框(1K / 2K / 4K,仅 Seedream 系列生效)
  • 处理模式下拉框(依次生成 / 并行生成)
  • 生成按钮

点生成后,每张图独立卡片展示:序号 + 提示词预览 + 图片 + 任务 ID + 单独下载按钮。

八、几个关键设计决策的复盘

决策 1:为什么不用 React/Vue

这个工具前端逻辑总共不到 150 行 JS。引入 React 要配 Babel、Webpack、JSX,构建链比业务逻辑还复杂。技术选型要看场景,不是越新越好。原生 JS + IIFE 对这种小工具是最佳解。

决策 2:为什么后端要做“下载图片到本地”这一步

生成的图片 URL 只有 24 小时有效期。如果前端直接用这个 URL,第二天分镜文件就全裂图了。所以后端必须把图片下载到本地 images/ 目录,前端拿的是本地路径 /images/xxx.png,永久有效。

这也是为什么有个 /images/ 路由——专门 serve 本地图片。

决策 3:为什么用 .env 而不是环境变量

环境变量要每次启动前手动 $env:API_KEY = "...",换台机器就忘。.env 文件跟着项目走(虽然不进 git),改一次永久生效,用 python-dotenv 一行加载:

from dotenv import load_dotenvload_dotenv()API_KEY = os.getenv("API_KEY")

开发体验比纯环境变量好太多。

最后修改这个文件,修改这两个变量 API_BASE_URL 和 API_KEY 为实际值:

决策 4:为什么单张失败不阻塞其他张

分镜生成是“批量但单张独立”的场景——第 3 张失败了,第 4、5、6 张照样该生成。所以每张生成单独 try/catch,失败的那张显示错误信息,成功的照常出图。这个容错设计让工具在弱网或 API 抖动时也不至于全盘崩溃。

九、后续可以加什么

这个版本是 MVP(最小可用版本)。如果要继续打磨,有几个方向可以考虑:

  1. 批量打包下载 —— 生成完 10 张图后,一键打包成 zip 下载,省得一张张点
  2. 提示词模板 —— 内置几套分镜模板(如“电影感”“赛博朋克”“水墨”),点一下自动填到输入框
  3. 历史记录 —— 把每次生成的 prompt + 图片路径存到 SQLite,方便回溯
  4. 图生图(reference_images) —— 上传一张参考图,让 AI 基于它改风格。ToAPIs 文档里这个能力是现成的,前端加个上传组件即可
  5. 进度条 —— 轮询时把 progress 字段(0-100)回传前端,做个真进度条,而不是干等

十、总结

打开后页面样式

输入提示词后等待样式

生成后结果

这个项目本身不复杂,但有几个点值得新手注意:

  1. 需求要抠清楚再动手 —— 一轮 brainstorming 省下后面 3 轮返工
  2. 读 API 文档比写代码重要 —— 同步还是异步、参数走顶层还是 metadata、URL 有效期多久,这些细节不看文档全是坑
  3. 小工具别上重框架 —— 原生 JS + Flask 单文件,部署简单、改起来快、看代码一目了然
  4. 容错要从单点做 —— 批量任务里每条单独 try/catch,一条挂了不影响其他
  5. 密钥管理要工程化 —— .env + .gitignore,别图省事硬编码
来源:https://juejin.cn/post/7660204851162808326
上一篇HCIE-AI大模型微调与安全治理 下一篇如何用Vibe Coding突破付费墙工作流 自制VS Code数据库扩展
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
跨境物流AI Agent感知决策全链路自动化技术拆解
AI教程 · 2026-07-11

跨境物流AI Agent感知决策全链路自动化技术拆解

2026年,跨境物流领域正迎来一场根本性变革——从“被动记录”全面迈向“主动执行”,AI智能体正在重塑整个行业格局。 你可能已经深有体会:每天一到岗,光是后台处理货件创建、物流追踪等重复操作,就要耗费数小时之久。行业调研数据显示,超过60%的运营人员每天至少花费2小时在这些机械性劳动上,而手动操作引

天学会AI应用开发第十二课:从PDF、Word和网页构建RAG
AI教程 · 2026-07-11

天学会AI应用开发第十二课:从PDF、Word和网页构建RAG

上一篇文章介绍了如何从TXT文件中读取文本内容,但在日常办公场景中,纯文本文件的使用频率并不高。更常见的需求是处理PDF、Word等文档格式,同时还需要从网页中提取知识信息。 因此,本篇文章将重点讲解如何从PDF、Word以及网页中提取内容,并将其应用于RAG(检索增强生成)系统。 一、从PDF文件

Hy3+WorkBuddy组合国产顶级Agent附完整提示词
AI教程 · 2026-07-11

Hy3+WorkBuddy组合国产顶级Agent附完整提示词

五个 Case 跑完,总结一下整体体验。工具使用能力:能不能自己开网页、找信息、标出处。规划能力:能不能把多约束需求拆成可执行步骤。长程执行能力:跨多步任务时会不会丢状态。复杂推理能力:能不能先推导、再写代码、再执行验证。WorkBuddy+Hy3 的表现完全符合预期。趁着 WorkBuddy 里的

AI Agent是什么?一文理解大语言模型、记忆、技能、工具、MCP、工作流与上下文
AI教程 · 2026-07-11

AI Agent是什么?一文理解大语言模型、记忆、技能、工具、MCP、工作流与上下文

智能体并非单一模型,而是由大语言模型、记忆、工具、工作流等模块协同构成的自主系统。它通过理解目标、检索记忆、调用工具、构建上下文、推理决策,并基于反馈闭环持续迭代,最终自主完成复杂任务。

DeepSeek决定自研芯片打造人工智能全新算力芯脏
AI教程 · 2026-07-11

DeepSeek决定自研芯片打造人工智能全新算力芯脏

被“逼”出来的第三条路。 一直以模型技术见长的DeepSeek,这次在算力供应链上迈出了让所有人侧目的一步。 2026年7月7日,路透社援引三位知情人士消息,DeepSeek正在悄然开发自有AI芯片。值得玩味的是,这颗芯片的定位非常精准——专攻推理,不涉足训练。消息人士称,项目大约启动于一年前,目前