Comic Frame
The little node that turns a raw panel into a comic panel
- image
- preview
- frame_data
If you've ever generated a batch of comic panels and tried to assemble them into a page, you already know the annoying part isn't the drawing - it's the frames. Comic Frame (class FrameNode) is the first brick in the Pixstri hierarchy: it takes one finished panel image and hands it a border, some padding, and an optional caption, so the raw output of a checkpoint actually reads as a comic panel instead of a floating rectangle on the canvas.
It's part of Pixstri ComfyUI Comics (lisaks/comfyui-panelforge), a small three-node pack for building comic pages top-down. FrameNode is the bottom of that stack: Comic Row stitches several frames side by side, and Comic Page stacks the rows into a full page. You don't really need this pack to draw comics - you need it to stop doing the layout by hand in an image editor.
How it works
Under the hood it's a short, honest PIL routine. It converts the incoming tensor to a PIL image, grows the canvas by border_width + padding on every side, fills it with the border color, draws a light-gray gutter (240,240,240) for the padding, pastes the original panel back on, and stamps your caption in the bottom-left corner. That's the whole mechanism - no masks, no fancy lettering, no model. It also only ever looks at the first image of a batch, so don't feed it a whole generated strip and expect five panels.
The inputs that matter
- image - your panel. This is the only non-optional input.
- border_width (0–20, default 2) - the black/white frame stroke. The single most "comic-looking" slider here.
- padding (0–50, default 5) - the light-gray gutter between border and art. Real print comics have this; cranking it makes panels feel airier.
- border_color -
blackorwhite. That's the whole palette. - caption (optional, multiline) - stamped at the bottom in PIL's default font.
Outputs: preview and frame_data
You get two outputs. preview is an IMAGE you can eyeball in the graph. The one that actually matters is frame_data - a FRAME_DATA dict carrying the processed image, its dimensions, and your caption. That's exactly what Comic Row expects on its frame1–frame5 inputs. Wire frame_data into a row, not the preview.
Here's the trap worth knowing before you build anything on it: FrameNode emits its IMAGE as a uint8 tensor, while ComfyUI's IMAGE convention is float in 0–1. The preview will look right, but if you run it straight into something like Save Image, the multiply-by-255 can blow the result out to white. Use the frame_data path into RowNode - that's the designed route, and RowNode handles the conversion for you.
Installing it
Via ComfyUI Manager, search "Pixstri" and hit install, or do it by hand:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/lisaks/comfyui-panelforge
# restart ComfyUI
No model files, no API, no keys - it's pure image math. One real gotcha: the README is boilerplate and its clone command says git clone https://github.com/yourusername/pixstri.git, which is a placeholder. Ignore it and use the URL above. The requirements.txt only lists torch and numpy, but the code needs Pillow - you'll get that from ComfyUI's own dependencies, so in practice nothing extra to install. As with any custom node, it runs with full access to your machine, so a quick skim of the source before installing is cheap insurance.
Troubleshooting
- Caption looks tiny or sits oddly - it's PIL's default font with crude positioning. It's a placeholder, not lettering. Don't build a title sequence on it.
- Saved output is blank/white while the preview looks fine - the uint8 thing above. Route through
frame_datainto a Row, or normalize before a Save node. - Only the first image of a batch gets framed - that's by design. One panel per FrameNode.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| border_width | INT | 20–20 | — |
| padding | INT | 50–50 | — |
| border_color | COMBO | 2 options: black, white | |
| captionopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| preview | IMAGE | — |
| frame_data | FRAME_DATA | — |