Nodes/comfyui-text-renderer/Render Text to Image
ComfyUI Node

Render Text to Image

Rendering Text You Can Actually Read — Then Letting the Model Ruin It, on Purpose

By kishida·Created 8 months ago·Updated 8 months ago· 1
Render Text to Image
    • IMAGE
    textHello World
    font_size48
    width512
    height512
    font_name
    text_color
    bg_color
    align
    outline_width0
    outline_color

    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), width and height (64–4096, step 64) - your canvas. Step of 64 is a polite nod to diffusion-native resolutions.
    • font_name - your system fonts, sorted, with a default that uses PIL's tiny built-in bitmap font. Heads up: that default font ignores font_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:
      cd ComfyUI/custom_nodes
      git clone https://github.com/kishida/comfyui-text-renderer
      then restart ComfyUI.

    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_width above 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.

    Categoryimage/text

    Inputs (10)

    NameTypeDefaultDescription
    textSTRINGHello World
    font_sizeINT488–500
    widthINT51264–4096
    heightINT51264–4096
    font_nameCOMBO46 options: default, C059, C059 (1), C059 (2), C059 (3), D050000L, +40
    text_colorCOMBO8 options: white, black, red, blue, green, yellow, +2
    bg_colorCOMBO7 options: black, white, transparent, red, blue, green, +1
    alignCOMBO3 options: left, center, right
    outline_widthINT00–20
    outline_colorCOMBO8 options: black, white, red, blue, green, yellow, +2

    Outputs (1)

    NameTypeDescription
    IMAGEIMAGE