ComfyUI Node

Comic Frame

The little node that turns a raw panel into a comic panel

By lisaks·Created about a year ago·Updated about a year ago· 8
Comic Frame
  • image
  • preview
  • frame_data
border_width2
padding5
border_color
caption

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 - black or white. 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 frame1frame5 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_data into 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.
CategoryPixstri/Comics

Inputs (5)

NameTypeDefaultDescription
imageIMAGE
border_widthINT20–20
paddingINT50–50
border_colorCOMBO2 options: black, white
captionoptSTRING

Outputs (2)

NameTypeDescription
previewIMAGE
frame_dataFRAME_DATA