Chat Overlay Node
The local step that actually puts replacement text on the image
- image
- IMAGE
Of the four nodes in ComfyUI-text-replace, this is the only one that works completely offline - no access token, no API call, no network. Give it an image, some rectangles, and some text, and it draws the text inside those boxes with a font it bundles itself. In the find → erase → rewrite pipeline that is the pack's whole reason to exist, Chat Overlay is the "rewrite."
The "Chat" in the name is misleading. There's no chat and no AI here. It's Pillow's ImageDraw doing the work: auto-sizing a font to fit each rectangle, wrapping your text into lines, and centering it. Deterministic, fast, and slightly rough around the edges.
How it works
The node takes two JSON strings and reconciles them. rectangles is a list of boxes, each with an id and left / top / width / height. texts is a dict mapping those ids to strings. For every box whose id has a matching non-empty text, it estimates a font size from the box area and the character count, wraps the text into lines, and draws each line centered in the box. Empty or missing text means that box gets skipped silently.
The inputs you'll actually set
- image - the canvas you're stamping on.
- rectangles - JSON like
[{"id": 1, "left": 0, "top": 0, "width": 100, "height": 100}]. - texts - JSON like
{"1": "Sample Text"}. The keys must match the ids. - font_name - an enum of 11 fonts, all bundled with the pack. They're Chinese typefaces (微软雅黑, 华文仿宋, 华文楷体, and friends), but they render Latin and ASCII text perfectly well. This is the closest thing to a personality toggle you get.
- font_color - 29 named colors, plus a
customoption that unlocks font_color_hex (default#000000) for arbitrary colors. - font_color_hex - only read when
font_coloriscustom. Setting it while a named color is selected does nothing.
One output: IMAGE, your original with text drawn on.
Where people get burned
The fit algorithm is a heuristic, not a typesetter. Short strings center beautifully; long strings can end up cramped because the font size is derived from a rough area-per-character estimate and it caps at the rectangle height. If a box is sized for a different character count, the text overflows or floats awkwardly - you'll be nudging rectangle sizes.
Two more quirks worth knowing. First, ids must match exactly between the two JSON fields; a mismatch means nothing renders and there's no error, just silence. Second, the node only draws on the first frame of the input - feed it a batch and frames after 0 come back untouched. And if your box height is really small, the while num_lines * font_size > height loop can shrink the font down to nothing, so keep boxes taller than a few pixels.
Install
Manager: search ComfyUI-text-replace, or:
cd ComfyUI/custom_nodes
git clone https://github.com/banqingyuan/ComfyUI-text-replace
Then restart. No models, no extra binaries - the only real requirement is Pillow, which ComfyUI already needs. The fonts ship inside the pack's nodes/fonts/ folder, so they appear in the dropdown the moment the pack loads.
The intended pairing is OCR Location Node → merged_rectangles output into rectangles here, then {"A": "your text"} keyed by the letters. If you're just slapping captions or labels on an image, you can also type the boxes by hand and skip OCR entirely. The auto-fit won't win any design awards, but for burning translated dialogue or replacement signage into an image, it does the job without touching the cloud.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| rectangles | STRING | [{"id": 1, "left": 0, "top": 0, "width": 100, "height": 100}] | — |
| texts | STRING | {"1": "Sample Text"} | — |
| font_name | COMBO | 11 options: 华文仿宋.ttf, 华文中宋.ttf, 华文新魏.ttf, 华文琥珀.ttf, 华文行楷.ttf, 华文彩云.ttf, +5 | |
| font_color | COMBO | 30 options: custom, white, black, red, green, blue, +24 | |
| font_color_hex | STRING | #000000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |