BD Save Workflow Image
The \"workflow included\" card, drawn by the graph itself
- image
- logo_image
- logo_mask
- card
- path
- status
ComfyUI can already export a picture of your canvas - right-click → Export (PNG/SVG). The catch is the words "right-click": it's manual, one at a time, and it only happens when you remember. BD Save Workflow Image is that same idea as a node, so the picture gets rendered during the run, titled, with the graph still embedded so the PNG opens by drag-and-drop.
If you post workflows or ship workflow templates, this is for you. If you only wanted the graph riding inside your output PNG, ComfyUI's own SaveImage already does that.
It does three jobs at once
Renders the BrainDead card. Same renderer the pack's template thumbnails come from (utils/thumbnail.py, lifted out of tools/make_thumbnail.py) - deliberately one implementation, so a node drawing its own card couldn't drift away from the thumbnails. Every knob the CLI accepts is exposed here, watermark included.
Takes its background from the graph, or from you. Left alone it draws a stylized LiteGraph-ish view of the current workflow: node boxes, bezier wires, BrainDead nodes titled in the accent colour. Connect an image and that still draws underneath - image_blend decides how much shows through.
Embeds the workflow. It writes workflow and prompt PNG text chunks the way SaveImage does, which makes the file re-openable, and why PNG is the default. JPEG has no text chunks, so a .jpg card is a picture of a workflow that cannot load as one.
How it finds the graph
Not on disk - in extra_pnginfo, which the frontend sends with every submission. If it isn't there (a headless caller that didn't post it), the status output says so instead of writing a file that looks fine and isn't. Same honesty for JPEG.
The outputs are card (the rendered IMAGE, for previewing in-graph), path (the absolute path written) and status (what was drawn, and whether the chunks went in).
The inputs that actually matter
- filename_prefix - a name under the ComfyUI output dir, or an absolute path. There's no auto-incrementing
_00001_counter here, so two runs at the defaultworkflow_cardand you've overwritten the first card. Fold something variable into it. - draw_graph / image / image_blend -
1.0is image only,0.0graph only,0.5mixes. Ignored with no image connected. - format / embed_workflow - keep them on
pngand true. That combination is the whole point. - title, subtitle, wordmark, bullets, chips, footnote, footer - the text chrome. First 8 bullets and first 6 chips are drawn; an empty
wordmarkhides that line and its dot. A blanktitlefalls back to the workflow's own name if the graph carries one, otherwise "Workflow" - don't leave it empty and then wonder why the card says Workflow. Replace the default BrainDeadfooter. - workflow_name / workflow_version / stamp_version - the version label appended to the subtitle line.
- accent / wordmark_color / background_color - hex (
#aa78ff) orr,g,b(170,120,255), both work. It's a text field because ComfyUI has no colour picker for custom nodes. - logo_image / logo_mask / logo_mask_inverted / logo_path / logo_height / logo_margin / logo_corner - the watermark, and where people lose ten minutes. A ComfyUI MASK is inverted alpha - 1 means transparent, and LoadImage emits it that way - hence the default on
logo_mask_inverted. Feed it a straight-alpha mask without flipping that to false and your logo is a blank square; connectlogo_imagewith no mask and it composites as an opaque rectangle.logo_pathpoints at a file on disk, which won't exist on a hosted ComfyUI, so use the IMAGE input there.
Install
Manager → search "BrainDead" → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Then restart. The pack is large - around 113 nodes, a bundled Blender, Pixal3D weights that download on first use - but none of that is triggered by this node. It needs PIL, numpy and torch, which your ComfyUI already has. The heavy lines in requirements.txt (moge, pinned utils3d/pipeline, natten) belong to the Pixal3D nodes and are imported defensively, so a failed optional install won't take the pack down. Manager will still try, so the install isn't instant.
It's a V3-API node, so run a current ComfyUI. It's also registered as an output node: it runs every queue. Note the category is BrainDead/save, not the cache group the README files everything else under.
Gotchas
- The card isn't your render. It's a separate file about the workflow, not a replacement for
SaveImage. You'll want both. - A JPEG card has no graph in it. That's a format limit, not a bug -
statuswill confirm it. - Sending the prompt from code? Include
extra_data.extra_pnginfo.workflow, or you get a lovely card with no graph drawn and nothing embedded. The frontend always sends it; your script has to. - Posting the PNG somewhere that recompresses - Reddit, most CDNs, any inline Discord preview - strips the text chunks. The card looks right and the file is no longer loadable.
Which is the honest summary of who this is for. The polish is chrome; the load-bearing part is embed_workflow on PNG, which any ComfyUI output already has. What this buys you is a publishing tool - one place that renders your pack's template thumbnails and the "workflow included" card you paste into a post, from the same code. If that's a weekly job, it earns its slot.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| filename_prefixopt | STRING | workflow_card | Output name under the ComfyUI output dir, or an absolute path. The extension is set by `format`. |
| titleopt | STRING | Big headline. Empty = the workflow's own name if one is known. | |
| subtitleopt | STRING | — | |
| wordmarkopt | STRING | BrainDead | The small top line above the title. Empty hides it and the accent dot. Colour it with wordmark_color. |
| wordmark_sizeopt | INT | 348–200 | Point size of the wordmark line. |
| bulletsopt | STRING | One bullet per line. First 8 are drawn. | |
| chipsopt | STRING | Comma-separated tag chips. First 6 are drawn. | |
| footnoteopt | STRING | — | |
| footeropt | STRING | BrainDeadGuild.com · BrainDead.TV · github.com/BizaNator/ComfyUI-BrainDead | Bottom bar text. Empty to omit. |
| imageopt | IMAGE | Use THIS as the background instead of drawing the graph — a screenshot, a render, anything. Wins over the graph. | |
| draw_graphopt | BOOLEAN | true | Auto-draw the current workflow as the background. STILL draws when an image is connected -- use image_blend to mix them. False = no graph. |
| image_blendopt | FLOAT | 1.000–1 | How much of the connected image to show over the graph. 1.0 = image only, 0.0 = graph only, 0.5 = both. Ignored with no image. |
| stamp_versionopt | BOOLEAN | true | Append the workflow name/version to the subtitle line. |
| workflow_nameopt | STRING | Label to stamp. Empty = taken from the graph if it carries one. | |
| workflow_versionopt | STRING | Version to stamp alongside the name, e.g. 'v16'. | |
| formatopt | COMBO | png | png embeds the workflow (openable in ComfyUI). jpg cannot carry text chunks — card only, no embedded graph. |
| embed_workflowopt | BOOLEAN | true | Write the workflow + prompt into the PNG text chunks, exactly as ComfyUI's SaveImage does. PNG only. |
| widthopt | INT | 1180256–8192 | — |
| heightopt | INT | 680256–8192 | — |
| qualityopt | INT | 881–100 | JPEG quality. Ignored for png. |
| accentopt | STRING | #aa78ff | Accent colour - top bar, bullets, the dot, BD node titles. Hex '#aa78ff' OR r,g,b '170,120,255' -- both work. ComfyUI has no colour-picker widget for custom nodes, so this is a text field. Clear it to fall back to the default. |
| wordmark_coloropt | STRING | #16a34a | Colour of the wordmark line. Hex '#aa78ff' OR r,g,b '170,120,255' -- both work. ComfyUI has no colour-picker widget for custom nodes, so this is a text field. Clear it to fall back to the default. |
| background_coloropt | STRING | #18181e | Card background. Hex '#aa78ff' OR r,g,b '170,120,255' -- both work. ComfyUI has no colour-picker widget for custom nodes, so this is a text field. Clear it to fall back to the default. |
| draw_logoopt | BOOLEAN | true | Composite the brand watermark. |
| logo_imageopt | IMAGE | Use THIS as the watermark instead of a file on disk. Wins over logo_path. Works on hosted ComfyUI, where a path would not exist. ComfyUI IMAGE is RGB, so connect logo_mask too or the logo composites as an opaque rectangle. | |
| logo_maskopt | MASK | Alpha for logo_image -- connect LoadImage's MASK output. Without it the logo has no transparency. | |
| logo_mask_invertedopt | BOOLEAN | true | ComfyUI's MASK is INVERTED alpha: 1 means transparent. LoadImage emits it that way, so this defaults to True. Set False only if your mask is already straight alpha (1 = opaque), otherwise the logo comes out as a blank square. |
| logo_pathopt | STRING | Watermark file on disk. Ignored when logo_image is connected. Empty = the repo logo. | |
| logo_heightopt | INT | 608–1024 | — |
| logo_marginopt | INT | 180–512 | — |
| logo_corneropt | COMBO | bottom-right | 4 options: bottom-right, bottom-left, top-right, top-left |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| card | IMAGE | The rendered card, for previewing in-graph. |
| path | STRING | Absolute path of the file written. |
| status | STRING | What was drawn and whether the workflow could be embedded. |