用Codex从零搭建一个脚本分镜图片生成器的流程步骤
效果图

为什么捣鼓这么个工具
做短视频、动画、漫画脚本的朋友,心里应该都有数——分镜这件事,绕不开。
传统的工作流长这样:编剧写好脚本,画师根据文字描述画出每一镜,然后来回修改。慢、贵、沟通成本还高,三座大山压上来,效率怎么能高得起来?
一个自然的念头就冒出来了:
能不能让AI直接根据分镜描述生成图片?
答案是肯定的,而且比想象中简单。现在的图像生成模型,像GPT-Image系列和豆包Seedream系列,已经能把文字描述转化为相当可用的画面。要做的,无非是把“输入文字→出图→保存”这串操作封装成一个顺手的小工具。
需求是怎么一步步清晰的
刚开始的想法很朴素:调OpenAI的画图API,输入提示词,出图,保存。但真正动手前,跟AI助手好好梳理了一遍需求。这一步确实重要,
模糊的需求,注定会带来返工
第一轮:交互形态
命令行还是Web页面?最终选择了
Web页面
第二轮:技术栈
前端用什么框架?
纯HTML加原生Ja vaScript
后端选了
Flask
第三轮:API Key的管理方式
环境变量还是页面输入?最初想用页面输入,方便演示,但很快意识到这是安全隐患。最终采用了
.env配置文件加python-dotenv自动加载
.env文件被.gitignore排除,密钥永远不会进入版本库。这才是工程化的做法。
第四轮:用哪个模型
这是关键转折点。一开始说“调OpenAI的画图API”,实际想用的是
gpt-image-2、gpt-image-2-vip、gpt-image-2-high
doubao-seedream-4-0/4-5/5-0
第五轮:要不要做视频
豆包Seedream系列其实能生成视频。但还是果断说
只做图片
读懂API文档:从同步到异步的踩坑记录
这是整个项目最关键的技术转折点。
最初按OpenAI标准接口写代码:直接用POST请求拿图片URL。结果发现第三方提供的图像生成是
异步的
第一次请求只返回task_id和状态,不返回图片。得拿着task_id去另一个接口轮询,直到状态变成completed,才能拿到真正的图片地址。
文档还给出了轮询策略建议:初始等待2秒,轮询间隔3秒,最大等待120秒,典型耗时5到30秒。
还有个坑:生成的图片URL有效期只有24小时。所以必须在拿到URL后立刻下载到本地,不能只存URL。
于是后端逻辑变成三步走:提交任务拿task_id,轮询状态每3秒查一次最多40次,下载图片保存到本地目录并返回本地URL给前端。
另外还有一个模型差异细节:
Seedream系列的分辨率参数要走metadata.resolution
resolution顶层字段。后端要根据model名字判断走哪条路。这种看文档才发现的小细节,是远程API集成最耗时的部分——没有捷径,就是读文档加试错。
前端:从单输入框到多输入框的演进
第一版前端就一个textarea,用户把所有分镜塞进去,用换行分隔。简单,但不好用:想删中间某一条得手动挪光标,看不清一共写了几条,没法对单条单独操作。
于是改成
动态多输入框
核心就是一段DOM操作。收集所有提示词时,遍历一遍输入框,提取非空内容。这个改动让交互体验好了很多。
依次生成 vs 并行生成:两种模式的设计
分镜一画就是十几张。如果一张一张串行生成,10张图每张20秒就得等3分钟。如果并行,理论上20秒就能全部拿回来。
所以加上了“处理模式”下拉框:
依次生成
并行生成
两种模式都用try/catch包裹单张生成,
一张失败不影响其他张
那些调试中的小坑
坑1:点击生成按钮没反应
部署完第一次点按钮,毫无响应。打开浏览器控制台才发现:Flask默认静态文件目录是
static/,访问路径必须写/static/script.js,不是/script.js。改一行就解决了。
坑2:API_BASE_URL写成了完整路径
.env里写了完整URL,但app.py又拼了一遍,导致最终URL重复。改成只写根域名,配置项只放根地址,路径在代码里拼——这是惯例,避免重复。
坑3:pip命令找不到
PowerShell里直接敲
pip install报无法识别。原因是没激活虚拟环境,且系统Python没把pip加进PATH。用py -m pip或激活虚拟环境后用python -m pip就解决了。
最终项目结构
整个项目的结构清晰明了:Flask后端负责异步任务、轮询和本地保存;前端负责多输入框管理、参数选择和结果展示;配置文件如.env不提交到版本库;运行时生成的图片存放在images/目录。
启动方式很简单:激活虚拟环境后运行python app.py,浏览器打开http://127.0.0.1:5000。界面包含提示词输入框(可新增)、模型下拉框、宽高比下拉框、分辨率下拉框、处理模式下拉框和生成按钮。
生成后,每张图以独立卡片展示,包含序号、提示词预览、图片、任务ID和单独下载按钮。
几个关键设计决策的复盘
决策1:为什么不用React/Vue
这个工具前端逻辑总共不到150行JS。引入React要配Babel、Webpack、JSX,构建链比业务逻辑还复杂。技术选型要看场景,不是越新越好。原生JS加IIFE对这种小工具是最佳解。
决策2:为什么后端要做“下载图片到本地”这一步
前面提到了,生成的图片URL只有24小时有效期。如果前端直接用它,第二天分镜文件就全裂图了。所以后端必须把图片下载到本地目录,前端拿的是本地路径,永久有效。这也是为什么专门有个路由来serve本地图片。
决策3:为什么用.env而不是环境变量
环境变量要每次启动前手动设置,换台机器就忘。
.env文件跟着项目走,改一次永久生效,用python-dotenv一行加载。开发体验比纯环境变量好太多。

决策4:为什么单张失败不阻塞其他张
分镜生成是“批量但单张独立”的场景——第3张失败了,第4、5、6张照样该生成。所以每张生成单独try/catch,失败的那张显示错误信息,成功的照常出图。这个容错设计让工具在弱网或API抖动时也不至于全盘崩溃。
后续可以加什么
这个版本是最小可用版本。如果要继续打磨,有几个方向值得考虑:
- ——生成完10张图后,一键打包成zip下载,省得一张张点
批量打包下载
- ——内置几套分镜模板,点一下自动填到输入框
提示词模板
- ——把每次生成的prompt和图片路径存到SQLite,方便回溯
历史记录
- ——上传一张参考图,让AI基于它改风格,这个能力是现成的
图生图(reference_images)
- ——轮询时把进度字段回传前端,做个真进度条,而不是干等
进度条
总结
打开后页面样式

输入提示词后等待样式

生成后结果

这个项目本身不复杂,但有几个值得新手注意的点:
- ——一轮brainstorming能省下后面三次返工
需求要抠清楚再动手
- ——同步还是异步、参数走顶层还是metadata、URL有效期多久,这些细节不看文档全是坑
读API文档比写代码重要
- ——原生JS加Flask单文件,部署简单、改起来快、看代码一目了然
小工具别上重框架
- ——批量任务里每条单独try/catch,一条挂了不影响其他
容错要从单点做
- ——
密钥管理要工程化
.env加.gitignore,别图省事硬编码