Nodes/GIF Toolkit/GIF Text Overlay
ComfyUI Node

GIF Text Overlay

Where the text actually gets burned into every frame

By oekobudde·Created 28 days ago·Updated 26 days ago· 1
GIF Text Overlay
  • images
  • style
  • images
◄fps8.0►
◄blink_enabledtrue►
◄blink_on_seconds0.50►
◄blink_off_seconds0.50►

The designer nodes are the fun part - you drag text around on a canvas and it looks great on one frame. Text Overlay is the part that makes it true for all forty frames. It takes the style object the designer produced, walks the whole batch, and renders the text onto each frame, with optional blinking.

This is the node sitting between Prepare / Preset and the export gate in the recommended wiring, and it's the one you'll rarely touch after setup.

How it works

The style object is a plain dictionary - {"enabled": true, "active_layer": 0, "layers": [...]} from the designer, or a flat single-style dict from GIF Text Style. The overlay doesn't care which; it normalises and renders.

For each frame it decides visible or not from the blink schedule: on-frames and off-frames are computed from blink_on_seconds and blink_off_seconds at the fps you gave it, round(seconds × fps) with a floor of one frame each, then frame_index % cycle < on_frames. Visible frames get every enabled layer painted on, in order - layer 3 sits over layer 2 sits over layer 1. Off frames are passed through as the untouched original.

Two fast exits worth knowing about, because they're why this node is cheap to leave in a graph: if the style's enabled flag is off, or if no enabled layer has non-empty text, the batch is returned completely unchanged without touching a single frame. That's the mechanism behind the pack's "turn off Enable text overlay and everything passes through" promise - no rewiring, no node bypass.

Text is drawn with PIL: multiline, centre-aligned, so a two-line caption stays centred on its anchor. The outline is a stroke of the width you set, the background is a rounded rectangle with alpha, and the shadow is the same text drawn offset behind it.

The inputs and output that matter

  • images (IMAGE) - the prepared batch.
  • style (GIF_TEXT_STYLE) - from GIF Multi-Text Designer, GIF Text Designer, or GIF Text Style. This is the socket that carries your whole look.
  • fps (FLOAT, default 8.0) - wire this from GIF Prepare / Preset. It's a plain widget, so it's easy to type 8 while the saver runs at 12, and then the blink rhythm is fast in the GIF and the text strobes. The number here and the frame_rate on your VHS Video Combine nodes should be the same number.
  • blink_enabled (BOOLEAN, default true) - off means the text is visible on every frame, all the time.
  • blink_on_seconds / blink_off_seconds (FLOAT, default 0.5 each).

Output is a single images (IMAGE) - same frame count, same resolution, text baked in. Straight into GIF Export Gate.

One limitation the author states outright: blink timing is global for all layers. You can't have the headline solid and the corner badge blinking on its own rhythm yet.

Install

Manager → search GIF Toolkit, or:

cd ComfyUI/custom_nodes
git clone https://github.com/oekobudde/ComfyUI-GIFToolkit.git

Full restart. No pip packages come with this pack; ComfyUI-VideoHelperSuite is the real requirement for the upstream video loading it assumes.

Common issues

Text appears, then vanishes for a few frames, then comes back. That's the blink doing its job. Set blink_enabled to false if you want it constant. Half-second on / half-second off is the shipped default and it's aggressive; 1.5 s / 0.5 s reads much better for a caption.

You changed the text in the designer and the export didn't move. Run the workflow again - the designer writes its style on execution, and the overlay reads whatever the last run handed it. Because the designer is deliberately always-dirty, one Run is enough; just don't expect the canvas edit alone to update the file.

The text strobes at the wrong speed. Check fps here against frame_rate on your combine nodes. Twenty seconds of confusion, every time.

Your colours are being ignored. Colour strings are parsed by PIL, which accepts #40e704, yellow, black, and other CSS-style names. A typo doesn't error - it falls back to a default. If something's stubbornly the wrong colour, retype the value rather than trusting the hex you think you pasted.

CategoryGIF Toolkit/Text

Inputs (6)

NameTypeDefaultDescription
imagesIMAGE—
fpsFLOAT8.00.1–120—
styleGIF_TEXT_STYLE—
blink_enabledBOOLEANtrue—
blink_on_secondsFLOAT0.500.05–10—
blink_off_secondsFLOAT0.500.05–10—

Outputs (1)

NameTypeDescription
imagesIMAGE—