Nodes/Comfyui_PDuse/PD_Text Overlay Node
ComfyUI Node

PD_Text Overlay Node

Burn text onto an image at a pixel-exact spot — the annotation node ComfyUI forgot

By 7BEII·Created 2 years ago·Updated 15 days ago· 53
PD_Text Overlay Node
  • image
  • IMAGE
textHello, ComfyUI!
font_size24.00
font_color#000000
position_x0.500
position_y0.500
letter_gap0.00
font_name

Put a label on it, exactly where you want it

PD_Text Overlay Node (PD_Text-Overlay-Node) draws text onto an image and lets you say precisely where it lands. Position is given as a fraction of the canvas (0 to 1 on each axis), so 0.5/0.5 is dead center on any resolution, and you get font size, color, letter spacing and a real font choice from the pack's bundled font folder. It's the node for watermarks, "效果图"/"原图" comparison labels, batch captions burned into previews, or any of the annotating people do constantly in this ecosystem and have to half-build themselves.

ComfyUI core is oddly light on "draw text here" - this is one of those workflow-utility gaps the KB's comfyui-ecosystem.md hints at: thousands of custom nodes exist to cover the 20% of operations the core doesn't ship. This node is that 20% for text overlays. Wire it after your final image and before Save Image, and the label rides along into the saved file.

How it works

The source uses PIL (ImageDraw, ImageFont) under the hood. It takes the first image in the batch, converts it to a PIL image, loads your chosen .ttf from the pack's fonts folder, then draws the text one character at a time - that per-character drawing is what makes letter_gap (negative or positive spacing) actually work. Position is computed as position_x * width and position_y * height, centered on the text's measured bounding box, so 0.5 really is middle. Color is hex, like #000000.

The font dropdown isn't hardcoded - it's generated by scanning the pack's fonts/ directory for .ttf files at load time. Drop a font in, restart, and it appears.

The inputs that matter

  • image - input tensor. Only the first image of a batch is processed - if you feed it 8 frames, you get 1 labeled frame back. That's the biggest surprise in the node.
  • text - what to draw (default "Hello, ComfyUI!").
  • font_size (float), font_color (hex string), position_x/position_y (0–1), letter_gap (−10 to 10).
  • font_name - chosen from fonts in the pack folder.
  • Output: IMAGE - the labeled image.

Installing it

Part of Comfyui_PDuse:

cd ComfyUI/custom_nodes
git clone https://github.com/7BEII/Comfyui_PDuse.git
cd Comfyui_PDuse
pip install -r requirements.txt

Or via ComfyUI Manager (search "Comfyui_PDuse") and restart. The pack ships a few fonts (Oswald, Caveat, and - the important ones for CJK - Alibaba-PuHuiTi, Source Han Sans, HYQiHei). Drop more .ttf/.otf files into ComfyUI/custom_nodes/Comfyui_PDuse/fonts to extend the list.

Where people get burned

Three classic complaints, all real. Chinese or Japanese text renders as boxes unless you pick a font with those glyphs - the ASCII-only fonts can't draw CJK, so reach for Alibaba-PuHuiTi or Source Han Sans. Only the first batch image comes back, which quietly loses frames in a video or batch workflow. And if the fonts folder is somehow empty at load, the node falls back to "Arial.ttf" and then to PIL's default font - which is tiny and ugly. Also, keep font_size sane relative to the canvas: oversized text just runs off the edge, and the node won't warn you. For single-image labeling it's dead simple; for batches, process one image at a time.

CategoryPDuse/Image

Inputs (8)

NameTypeDefaultDescription
imageIMAGE
textSTRINGHello, ComfyUI!
font_sizeFLOAT24.00
font_colorSTRING#000000
position_xFLOAT0.5000–1
position_yFLOAT0.5000–1
letter_gapFLOAT0.00-10–10
font_nameCOMBO7 options: Oswald-Bold.ttf, Caveat-VariableFont_wght.ttf, Alibaba-PuHuiTi-Heavy.ttf, sign_Caveat-VariableFont_wght.ttf, Quicksand-Bold.ttf, FZ_HTK_light.TTF, +1

Outputs (1)

NameTypeDescription
IMAGEIMAGE