Render Text to Image
Rendering Text You Can Actually Read — Then Letting the Model Ruin It, on Purpose
- IMAGE
Diffusion models are famously bad at drawing text. Give a checkpoint a prompt like "a neon sign reading OPEN," and you get OPEN or OPÉN or a scramble of glyphs that only a mother could love. That's why almost every serious workflow throws "text" into the negative prompt and gives up on legible words entirely.
Render Text to Image (TextRenderNode) takes the opposite route: instead of begging the model to spell, you draw the text yourself - pixel-perfect, any font, any size - and feed that image back in as a hint. The author is upfront about the scope: this is for making a hint for text rendering in image AI, not a rich-text decoration tool. No watermarking, no fancy layout. One node, one job.
The pattern this enables is a classic one. Render your text on a clean canvas, then run it through img2img at low denoise (or mask the text area and inpaint, or pipe it through ControlNet), and the model re-renders your clean text into the scene with lighting, perspective, and texture. This is the same "exact placement" argument that keeps masked inpainting alive: you decide where the text sits, the model makes it look like it belongs there.
How it works
The mechanism is blessedly simple - pure PIL, no models, no VRAM, instant. On startup the node scans your OS font directories (Windows, macOS, and Linux paths are all handled), reads each font's family name, and builds the font_name dropdown. When you hit run, it draws your text onto an RGBA canvas with ImageDraw, applies an optional outline, and converts the result to a standard [1, height, width, 3] IMAGE tensor. No checkpoints, no LoRAs, no downloads. It's as close to dependency-free as a ComfyUI node gets.
The inputs that matter
There are ten inputs and honestly you'll tune four of them:
text- multiline, default "Hello World". It does not wrap, so on a small canvas a long line just overflows. Give it width or keep it short.font_size(8–500, default 48),widthandheight(64–4096, step 64) - your canvas. Step of 64 is a polite nod to diffusion-native resolutions.font_name- your system fonts, sorted, with adefaultthat uses PIL's tiny built-in bitmap font. Heads up: that default font ignoresfont_size- it stays bitmappy and small no matter what you set.align- left/center/right horizontally. Vertically it's always centered.
The rest - text_color, bg_color, outline_width, outline_color - are the obvious pickers. One output: IMAGE, which wires into any img2img, VAE encode, or ControlNet input.
Installing it
Two ways, the same as any pack:
- ComfyUI Manager: search "comfyui-text-renderer" and hit Install, or
- Manual:
then restart ComfyUI.cd ComfyUI/custom_nodes git clone https://github.com/kishida/comfyui-text-renderer
There's no requirements.txt - PIL and torch are already in ComfyUI. The one optional extra: fonttools, if you want the dropdown to show family names ("DejaVu Sans") instead of filenames. On Windows that's python_embeded\python -m pip install fonttools.
Where people get burned
- "Transparent" background becomes black. The output converts to RGB, so the alpha channel gets dropped and transparent flattens to black. If you need a see-through result, you'll have to composite before it exits this node.
- The font list is cached at startup. Install a new font and it won't appear until you restart ComfyUI.
- The outline is chunky. It's drawn as square offset copies of the text, not a smooth stroke, so at
outline_widthabove 2 it looks blocky. Fine for hints, wrong tool for badges. - Portability. The dropdown is a snapshot of your machine's fonts, so a workflow using "C059" breaks on a machine without it. Stick to the DejaVu defaults if you're sharing.
Is it the flashiest node you'll install? No. But it's the honest workhorse for that one stubborn problem - legible text - that no checkpoint has fully solved.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Hello World | — |
| font_size | INT | 488–500 | — |
| width | INT | 51264–4096 | — |
| height | INT | 51264–4096 | — |
| font_name | COMBO | 46 options: default, C059, C059 (1), C059 (2), C059 (3), D050000L, +40 | |
| text_color | COMBO | 8 options: white, black, red, blue, green, yellow, +2 | |
| bg_color | COMBO | 7 options: black, white, transparent, red, blue, green, +1 | |
| align | COMBO | 3 options: left, center, right | |
| outline_width | INT | 00–20 | — |
| outline_color | COMBO | 8 options: black, white, red, blue, green, yellow, +2 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |