KIE • Storyboard Contact Sheet
A real storyboard image, rendered on your own GPU
- hero_frame_1
- hero_frame_2
- hero_frame_3
- hero_frame_4
- hero_frame_5
- hero_frame_6
- contact_sheet
- storyboard_json
- saved_files_json
A shot list in a text box is a shot list. A grid of numbered cards with a prompt, a duration, and the camera language on each one is a storyboard you can actually review - or hand to somebody else.
KIE • Storyboard Contact Sheet takes the shot sequence JSON and renders it as a single image, with optional hero frames pasted into the cards. It's local Pillow rendering: no KIE call, no credits, no key. It's an output node, so the sheet appears when you queue and gets saved under output/KIE-Storyboards/.
What the sheet looks like
Cards are laid out in a grid, three columns at most, filling top-left to bottom-right in shot order. Each card holds:
- a hero frame if you connected one, letterboxed to fit, otherwise a "NO HERO FRAME" placeholder;
SHOT 03 | 6sin the header line;- the first two lines of the prompt, wrapped;
- the camera direction - shot size, angle, movement - in blue;
- the
editorial_intentfrom the draft node in amber, if the plan carries one.
That amber line is the underrated bit. It's the draft node's stated reason for the shot ("land on a telling detail", "increase momentum"), printed next to the prompt, so you can see at a glance where the plan drifts from what you meant.
The output is also written into the graph as a normal preview, and the same persistent machinery the pack uses elsewhere means the image reference is stored in the workflow rather than lost on reload.
Inputs and outputs
- shot_sequence_json - forced input. Wire it from KIE • Script to Shot Draft or, better, KIE • Shot Plan Review so you're storyboarding the version you edited.
- hero_frame_1 … hero_frame_6 - optional
IMAGEsockets, one per shot. Connect real frames from a Load Image node, a previous generation, or a character reference. Not every slot needs filling, and you can't connect one beyond the number of planned shots - the node errors if you try.
Outputs:
- contact_sheet - the rendered
IMAGE. Display it, feed it to an upscaler, or wire it to a vision model if you want a caption. - storyboard_json - metadata per shot: prompt, duration, camera, editorial intent,
direction_mode, andhero_frame_connectedso you know which cards are placeholders. - saved_files_json - the saved file record for the sheet under
output/KIE-Storyboards/.
The hero-frame rule nobody expects
Each hero_frame_N socket accepts exactly one image. Not a batch. If you feed it an IMAGE batch of four, you get:
hero_frame_2 must be one ComfyUI IMAGE, not an image batch.
This is the single most common error people hit with this node, because everything upstream usually produces batches. Select a single frame first (an image-select or batch-index node), then connect it. Same story for RGBA/RGB channel expectations - a 4-channel RGBA image is fine, anything else isn't.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/felipederosilva/ComfyUI-KIE-Nodes-Next
cd ComfyUI-KIE-Nodes-Next
pip install -r requirements.txt
Restart. It lives under KIE Next / Studio / Direction. Pillow is in the pack's requirements, so rendering works out of the box. One cosmetic thing on Linux: card text uses Arial if the system has it and falls back to PIL's tiny bitmap font if not, so the labels will be small but readable on a bare container.
Gotchas
"A storyboard needs 1 to 6 shots from Shot Sequence." The connected JSON isn't an array within range. If you hand-rolled the string, check it parses.
"A hero frame is connected beyond the 3 planned shots." You filled slot 5 on a three-shot plan. Disconnect it, or extend the plan.
The sheet doesn't update. It's an output node - nothing renders until you queue. Editing the JSON in a text widget upstream needs a Queue to take effect.
Read it as a plan, not a promise. The sheets that say "NO HERO FRAME" across the board are the normal case for a first pass: you're reviewing the intent of each shot before spending anything on frames.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| shot_sequence_json | STRING | — | |
| hero_frame_1opt | IMAGE | — | |
| hero_frame_2opt | IMAGE | — | |
| hero_frame_3opt | IMAGE | — | |
| hero_frame_4opt | IMAGE | — | |
| hero_frame_5opt | IMAGE | — | |
| hero_frame_6opt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| contact_sheet | IMAGE | — |
| storyboard_json | STRING | — |
| saved_files_json | STRING | — |