Quick Animatic Boards
Quickly iterate on animatic or hero keyframe boards driven by your own art.
About
Quick Animatic Boards is a lightweight ComfyUI workflow for rapidly turning your own sketches, beats, or thumbnails into clean 16:9 animatic or hero keyframe boards. It standardizes your artwork to a storyboard-friendly frame, adds concise shot notes generated by an LLM, and lets you preview and export with minimal friction. You load your art via LoadImage, set a target resolution with PrimitiveNode (e.g., 1920x1080), and iterate quickly by previewing in PreviewAny before saving with SaveImage.
Technically, the workflow routes your image through a small set of custom utility nodes (IDs: d33c1791-dfd2-4102-8540-aa63e4434cd2, f2228dc9-64e8-43b1-a4ca-b8a57eed8f64, e3dd2fcb-0e5e-47a8-963b-adea96749eb0, 601fd020-3eba-4b24-b15f-a2a9c0307d3a, eaabb89a-2cd6-4960-ad44-1b152bff77c1, 86a340d1-ba23-44b6-8470-6b3d64167d65) that handle layout and final compositing to a 16:9 frame, with Reroute nodes keeping the graph clean. GeminiNode is used to synthesize or refine brief shot notes from your text prompt (and, if supported by your Gemini node variant, the loaded image).
Notes are displayed in PreviewAny so you can copy them into production docs; some layouts may also render text onto the frame if that branch is enabled. Because it uses no diffusion sampler, iteration is fast and predictable—ideal for blocking sequences or creating polished hero frames from your own art.
What you provide
- Reading the workflow
Runs in ComfyUI. This workflow can't run on this page. Open it in Comfy Cloud with everything loaded, or download it for your own ComfyUI.
Try in CloudInside the workflow
A read-only preview of the node graph. Open it in Comfy Cloud or download it to edit the nodes.
Loading the graph
Open full-size workflow preview- Author
- ComfyUI
Requires custom nodes
- Reading the workflow
Use this workflow from code
Generated from the workflow graph and inputs when possible; stored examples are shown otherwise. Review credentials and endpoints before running code, which may incur charges.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"1": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"2",
0
]
},
"_meta": {
"title": "Preview All Generated Prompts"
}
},
"2": {
"class_type": "GeminiNode",
"inputs": {
"images": [
"6",
0
],
"model": "gemini-3-pro-preview",
"prompt": "Generate 6 different prompts following the instructions below. \nEach prompt idea needs to be 50-80 words max and be separated by *.\nEach prompt should be unique, varying the camera angles and shot type. Add subtle detail and maintain consistent elements.",
"seed": 12345,
"system_prompt": ""
},
"_meta": {
"title": "Google Gemini"
}
},
"5": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_1",
"images": [
"10:69",
0
]
},
"_meta": {
"title": "Save Image 1"
}
},
"6": {
"class_type": "LoadImage",
"inputs": {
"image": "f076b4b3a7d2968cb0382a93479cf1e5af6117ccf4427bf131097b2daabfa6b4.png"
},
"_meta": {
"title": "Load Reference Image"
}
},
"11": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"10:67:64",
0
]
},
"_meta": {
"title": "Preview Prompt 1"
}
},
"18": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_2",
"images": [
"19:72",
0
]
},
"_meta": {
"title": "Save Image 1"
}
},
"20": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"19:70:80",
0
]
},
"_meta": {
"title": "Preview Prompt 2"
}
},
"21": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_3",
"images": [
"22:85",
0
]
},
"_meta": {
"title": "Save Image 3"
}
},
"23": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"22:83:93",
0
]
},
"_meta": {
"title": "Preview Prompt 3"
}
},
"24": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_4",
"images": [
"25:98",
0
]
},
"_meta": {
"title": "Save Image 4"
}
},
"26": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"25:96:113",
0
]
},
"_meta": {
"title": "Preview Prompt 4"
}
},
"27": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_5",
"images": [
"28:101",
0
]
},
"_meta": {
"title": "Save Image 5"
}
},
"29": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"28:99:121",
0
]
},
"_meta": {
"title": "Preview Prompt 5"
}
},
"30": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_6",
"images": [
"31:106",
0
]
},
"_meta": {
"title": "Save Image 6"
}
},
"32": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"31:104:129",
0
]
},
"_meta": {
"title": "Preview Prompt 6"
}
},
"10:67:3": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"10:67:9",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"10:67:62": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"10:67:64": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"10:67:8",
0
],
"string": [
"10:67:66",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"10:67:65": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"10:67:64",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"10:67:66": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"10:67:8": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"10:67:3",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"10:67:9": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"10:67:62",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"10:68": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"10:69",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"10:69": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"10:67:64",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 1,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"19:70:75": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"19:70:78",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"19:70:76": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 2
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"19:70:77": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"19:70:76",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"19:70:78": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"19:70:77",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"19:70:80": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"19:70:75",
0
],
"string": [
"19:70:82",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"19:70:81": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"19:70:80",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"19:70:82": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"19:71": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"19:72",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"19:72": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"19:70:80",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 2,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"19:73": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"6",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"19:74": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"19:71",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"22:83:88": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"22:83:91",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"22:83:89": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 3
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"22:83:90": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"22:83:89",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"22:83:91": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"22:83:90",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"22:83:93": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"22:83:88",
0
],
"string": [
"22:83:95",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"22:83:94": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"22:83:93",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"22:83:95": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"22:84": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"22:85",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"22:85": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"22:83:93",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 3,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"22:86": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"6",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"22:87": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"22:84",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"25:96:108": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"25:96:111",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"25:96:109": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 4
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"25:96:110": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"25:96:109",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"25:96:111": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"25:96:110",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"25:96:113": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"25:96:108",
0
],
"string": [
"25:96:115",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"25:96:114": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"25:96:113",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"25:96:115": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"25:97": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"25:98",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"25:98": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"25:96:113",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 4,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"28:100": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"28:101",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"28:101": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"28:99:121",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 5,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"28:102": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"6",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"28:103": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"28:100",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"28:99:116": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"28:99:119",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"28:99:117": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"28:99:118": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"28:99:117",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"28:99:119": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"28:99:118",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"28:99:121": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"28:99:116",
0
],
"string": [
"28:99:123",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"28:99:122": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"28:99:121",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"28:99:123": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"31:104:124": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "(?<=\\{)\\d+(?=\\})",
"replace": [
"31:104:127",
0
],
"string": "(?:^(?!\\s*\\*?\\s*$).+$\\n(?:^\\s*\\*?\\s*$\\n)*){0}^(?!\\s*\\*?\\s*$)(.+)$"
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"31:104:125": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 6
},
"_meta": {
"title": "Int - Select Prompt Number (not index)"
}
},
"31:104:126": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"31:104:125",
0
],
"b": 0,
"value": "a-1"
},
"_meta": {
"title": "Convert Prompt Number to Index"
}
},
"31:104:127": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"31:104:126",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"31:104:129": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": [
"31:104:124",
0
],
"string": [
"31:104:131",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"31:104:130": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"31:104:129",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"31:104:131": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"2",
0
]
},
"_meta": {
"title": "Text (Multiline)"
}
},
"31:105": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"6",
0
],
"images.image1": [
"31:106",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"31:106": {
"class_type": "GeminiImage2Node",
"inputs": {
"aspect_ratio": "16:9",
"images": [
"6",
0
],
"model": "gemini-3-pro-image-preview",
"prompt": [
"31:104:129",
0
],
"resolution": "2K",
"response_modalities": "IMAGE+TEXT",
"seed": 6,
"system_prompt": "You are an expert image-generation engine. You must ALWAYS produce an image.\nInterpret all user input—regardless of format, intent, or abstraction—as literal visual directives for image composition.\nIf a prompt is conversational or lacks specific visual details, you must creatively invent a concrete visual scenario that depicts the concept.\nPrioritize generating the visual representation above any text, formatting, or conversational requests."
},
"_meta": {
"title": "Nano Banana Pro (Google Gemini Image)"
}
},
"31:107": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"31:105",
0
]
},
"_meta": {
"title": "Preview Image"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)Questions & answers
No. This workflow does not generate new imagery. It standardizes your existing art to a 16:9 frame and uses GeminiNode to produce optional shot notes, so iteration is fast and consistent.
Update the width and height values in the PrimitiveNode. For 16:9, use sizes like 1920x1080 or 1280x720. If you switch to another aspect ratio, ensure any layout or crop nodes downstream are adjusted accordingly.
Use the model your Gemini node supports that balances speed and quality for note generation (for example, a ‘Pro’ model for richer notes or a ‘Lite’ model for faster iterations). Configure this inside GeminiNode along with your API key.
This template focuses on single frames for rapid iteration. To batch, run the workflow repeatedly with different images, or extend it by adding a batch image loader and connecting it to the same layout and save path.