DAELAB - GPT Image 2 StoryBoard
A shot list that pays per row, on Comfy credits
- images
- image
Storyboarding is the one part of image generation that's been solved by spreadsheets for decades: numbered shots, a description each, maybe a reference. What you usually can't do is turn that spreadsheet into actual images without clicking through a form fifty times.
DAELAB - GPT Image 2 StoryBoard is that spreadsheet, inside ComfyUI. Rows are shots. Each row becomes one GPT Image 2 call. The whole thing runs on your ComfyUI account credits, not an OpenAI API key - the node forwards your signed-in request's credentials into the nested execution and never writes auth into the workflow or to disk. That's the headline, and it's the reason it can exist at all.
How it runs
The node's own table is the editor: 镜号 (shot number), 时长, 画面提示词 (the visual description), optional shot notes, optional reference image. You fill it in, or you upload a storyboard document - DOCX, XLSX/XLSM, CSV, TSV, TXT, Markdown, PDF - and the built-in parser maps its columns in. Voiceover, narration and dialogue columns are explicitly ignored, which is a good sign: someone actually used this on real scripts.
On execution each valid shot calls ComfyUI's native OpenAIGPTImageNodeV2 once, hard-wired to gpt-image-2 with n=1. Generation is serial, not parallel, and if it's interrupted the finished images hang around in a temp directory for up to six hours, so re-running with the same content resumes from the failed shot instead of re-billing the successful ones.
The outputs are images (COMFYTV_IMAGES, the whole batch) and image (COMFYTV_IMAGE, the currently selected frame). Those are ComfyTV's type names, reused so generated results still connect to ComfyTV's downstream batch nodes - the node imports no ComfyTV code and doesn't modify it, it just speaks the same protocol.
Inputs a beginner actually touches
storyboard_data is the table state (JSON, hidden in the panel). selected_index picks which row that single image output reflects. main_prompt is a shared style string applied to every shot - put your look here, not in nineteen rows.
Generation settings map to the native node: size (default auto), custom_width/custom_height (1024 each, used when something other than a preset is needed), background (default auto), quality (default low, with the tooltip's own warning: higher quality consumes more ComfyUI credits), and seed. workflow selects the underlying API workflow and defaults to "OpenAI GPT Image 2 (Comfy Credits)".
The rest is plumbing you mostly won't touch: force_run_token to trigger a run, project_id and parent_output_id for grouping and lineage, custom_params as a JSON escape hatch, and the optional imported_storyboard for feeding in a parsed document.
The honest economics
Every row is a billable partner-node call on a cache miss. A twenty-shot board at low is twenty calls; at high it's twenty more expensive ones. The default of low is not an oversight - it's the correct default for boards where you're checking composition, not grain.
Iterate in two passes. Board at low, look at the whole thing, fix the descriptions, then re-run only the shots you like. Because each shot is its own row, you can prune rows rather than fight a batch. And because the node resumes after an interruption, a mid-run credit hiccup doesn't cost you the frames you already paid for.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library.git
Restart ComfyUI, refresh the browser. Unlike most of this pack, this node does want the extra Python dependencies: python-docx, openpyxl and pdfplumber are declared in the repo's requirements.txt and are what make DOCX/XLSX/PDF import work. Without them the node runs fine but document upload fails. Install them in ComfyUI's own environment:
cd ComfyUI
python -m pip install -r custom_nodes/ComfyUI-DAELab-Custom-Nodes-Library/requirements.txt
You'll also need to be signed in to a Comfy account, since the child node is a partner node.
Gotchas
Blank descriptions get skipped, which is usually what you want - but it means a row that "didn't generate" is often a row you didn't actually fill in.
The reference-image column is optional and separate from the video-workflow's reference semantics. If you're also running the pack's table/video generation, don't assume a column marked as a reference for video will be picked up here; the README is explicit that image material mapping and video column marking are handled separately.
And the whole workflow of this node assumes the GPT Image 2 partner node is available in your ComfyUI version and that you're signed in. If the nested call fails with an auth error rather than a prompt error, that's the first thing to check.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | — |
| project_id | STRING | — | |
| parent_output_id | INT | 00–2147483647 | — |
| workflow | COMBO | OpenAI GPT Image 2 (Comfy Credits) | 1 options: OpenAI GPT Image 2 (Comfy Credits) |
| size | COMBO | auto | 10 options: auto, 1024x1024, 1024x1536, 1536x1024, 2048x2048, 2048x1152, +4 |
| custom_width | INT | 10241024–3840 | — |
| custom_height | INT | 10241024–3840 | — |
| background | COMBO | auto | 2 options: auto, opaque |
| quality | COMBO | low | Higher quality consumes more ComfyUI credits. |
| seed | INT | 00–2147483647 | — |
| main_prompt | STRING | Optional style shared by every storyboard shot. | |
| storyboard_data | STRING | DAELab storyboard editor state (JSON). | |
| selected_index | INT | 11–999 | — |
| custom_params | STRING | {} | — |
| imported_storyboardopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| images | COMFYTV_IMAGES | — |
| image | COMFYTV_IMAGE | — |