Nodes/ComfyUI_OverlayFrameNumber/Overlay Frame Number
ComfyUI Node

Overlay Frame Number

Burning a Frame Counter Into Your Video Batch (So You Can Actually Tell Frame 40 From Frame 90)

By casc1701·Created 11 months ago·Updated 8 months ago· 0
Overlay Frame Number
  • images
  • IMAGE
frame_number1
positionbottom-right
font_size48
font_color#FFFFFF
background_color#00000000
outline_color#000000
outline_width2
font_fileNone
text_padding10
num_padding4

The one-job node you didn't know you needed

Overlay Frame Number stamps a big readable counter onto every image in a batch, so when a 121-frame WAN or LTX video render dumps its frames you can finally tell which one is which. If you've ever squinted at a wall of nearly-identical preview images trying to find where the motion breaks, this is the fix. It's a pure post-processing utility: nothing generative, no models, no API - just Pillow drawing text onto an IMAGE tensor.

It started as one person's itch. The author made it because FFmpeg could do the job but they wanted the counter inside the ComfyUI graph to review WAN renders over 81 frames, and they were open about getting an AI assistant to write it. The README literally brags "a Monkey using grok wrote it." It's a simple tool with a real backstory - take the wink, but the node works.

How it works

You drop it after VAE Decode (or any node that emits a batched IMAGE) and it walks each frame individually: converts the tensor to a PIL image, draws your number with ImageDraw, and hands the whole batch back unchanged in size or quality. The clever bit: it doesn't stamp the same number on every frame. With a batch of 4 and frame_number set to 10, you get 10, 11, 12, 13 - frame_number is a starting counter, so it behaves like an actual frame counter across your video, not a static watermark.

The inputs that matter

There are a lot of knobs, but a beginner only touches a few:

  • images - the IMAGE batch in, and the only input you must wire.
  • frame_number - where the counter starts (min 1).
  • position - one of five spots: top/bottom-left/right or center. Bottom-right is the default.
  • num_padding - zero-padding, default 4, so frame 1 renders as 0001. Bump to 6+ for long videos so numbers don't get wider mid-render.
  • font_size - 12 to 200, default 48.

The rest are styling: font_color, outline_color and outline_width (the dark outline is what keeps the number readable on white skies), text_padding, and background_color - which defaults to #00000000, i.e. fully transparent, so you get no box until you ask for one. Give it an 8-digit hex like #80000000 for a translucent dark bar instead. The single output is an IMAGE, ready to feed straight into a preview or Save node.

Installing it

The easy route is ComfyUI Manager - search "OverlayFrameNumber". Otherwise:

cd ComfyUI/custom_nodes
git clone https://github.com/casc1701/ComfyUI_OverlayFrameNumber
cd ComfyUI_OverlayFrameNumber
pip install -r requirements.txt

Then restart ComfyUI. Dependencies are blessedly light: just Pillow>=9.0.0 and fontconfig on Linux. No model files, nothing to download - if you're running ComfyUI at all, you basically already have what this needs.

Where people get burned

Two traps. First: on Linux there's usually no arial.ttf, so with font_file left on "None" you can silently fall back to Pillow's tiny built-in bitmap font and get unreadably small text - that's the classic "why is my number microscopic" report. Set font_file to a real system font from the dropdown, or drop a .ttf into the node's own folder and restart. The dropdown is built by scanning your font directories at startup, so new fonts need a restart to appear.

Second, and mildly annoying: the README and package description promise a "customizable prefix," but the shipped node has no prefix input. The name is a slight lie - you get zero-padding, not frame_0001. That's fine in practice (most people just want the digits), but don't hunt for a knob that isn't there. If you genuinely need per-frame numbering for a long render, this is one of the few tools that does it in-graph, and it's the one I'd reach for.

Categoryimage/postprocessing

Inputs (11)

NameTypeDefaultDescription
imagesIMAGE
frame_numberINT11–99999
positionCOMBObottom-right5 options: top-left, top-right, bottom-left, bottom-right, center
font_sizeINT4812–200
font_colorSTRING#FFFFFF
background_colorSTRING#00000000
outline_colorSTRING#000000
outline_widthINT20–10
font_fileCOMBONone46 options: None, /usr/share/fonts/opentype/urw-base35/C059-BdIta.otf, /usr/share/fonts/opentype/urw-base35/C059-Bold.otf, /usr/share/fonts/opentype/urw-base35/C059-Italic.otf, /usr/share/fonts/opentype/urw-base35/C059-Roman.otf, /usr/share/fonts/opentype/urw-base35/D050000L.otf, +40
text_paddingINT100–50
num_paddingINT41–8

Outputs (1)

NameTypeDescription
IMAGEIMAGE