ComfyUI Node

Text Image

Render text to a real image (and a mask) without leaving ComfyUI

By wenchengxiang·Created about a month ago·Updated a day ago· 1
Text Image
  • size_as
  • image
  • mask
texttext
font_filePuHui.ttf
aligncenter
char_per_line80
leading8
font_size72
text_color#FFFFFF
stroke_width0
stroke_color#FF8000
x_offset0
y_offset0
width512
height512

Text Image turns a string of text into an actual raster image - and a matching mask - right inside ComfyUI, no external image editor, no API. You type some words, pick a font size and color, and it renders them onto a canvas you control. If you've ever burned a label onto an image, stamped a caption into a training set, or wanted a watermark that's part of the tensor pipeline rather than a post-editing afterthought, this is the node.

Where it earns its keep: dataset prep is the big one. Caption your own training images by compositing text directly into the pixel stream, or generate synthetic text-over-image samples for OCR-ish tasks. Then there's workflow polish - stamping "raw" or the seed onto a preview, adding a frame counter to a video contact sheet, watermarking before export. Because it's a real IMAGE output, anything downstream that composites pixels will take it, and because it also outputs a MASK, you can do clean alpha-aware compositing instead of compositing a black-background box and hoping it blends.

The one thing to know up front: the font dropdown has a single entry - the pack ships Alibaba-PuHuiTi-Heavy.ttf, a chunky, modern Chinese-friendly display font, and the node enumerates its own fonts folder at load time. If you want another typeface, drop a .ttf/.otf/.ttc file into ComfyUI/custom_nodes/ComfyUI-Practical-Tools/fonts/ and restart; it'll show up in the dropdown.

How it works

It's Pillow under the hood (which ComfyUI already ships): the node builds a PIL canvas at your width × height, wraps the text to char_per_line characters per line, and draws with your font size, alignment, and optional stroke (outline). Controls worth knowing:

  • text - the multiline content.
  • font_size - default 72, up to 2500. Bigger than you think you need at 512px.
  • char_per_line (default 80) and leading (default 8, extra line spacing) - control how text wraps and breathes.
  • text_color / stroke_color - hex strings like #FFFFFF. stroke_width - outline thickness; 0 means no outline.
  • align - center/left/right, with x_offset/y_offset nudging the block.
  • size_as - the wildcard input: wire any IMAGE or MASK in and the canvas snaps to that image's dimensions, ignoring width/height. That's the "match my existing image exactly" trick for compositing.

Outputs are image (RGB IMAGE) and mask (the rendered text as an alpha MASK, black background / white glyphs) - wire the mask into a blend or composite node for clean edges.

How to install it

Part of ComfyUI-Practical-Tools by wenchengxiang. ComfyUI Manager → search ComfyUI-Practical-Tools → install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/wenchengxiang/ComfyUI-Practical-Tools

Needs Pillow (already bundled with ComfyUI). No model downloads, no keys.

Common issues

  • "The font dropdown is empty." The node only scans its own fonts/ folder. If you deleted it or installed oddly, you'll see a <No fonts found> placeholder and the node errors when it runs - re-extract the pack or add your own font file.
  • Text overflowing the canvas. Wrapping is by character count, not by measured width - a string of wide glyphs or a huge font size can still run past the right edge or get clipped. Crank up width or lower font_size/char_per_line.
  • The mask looks inverted for some blend nodes. Different composite nodes expect black-as-transparent or white-as-transparent. If your text composites as a hole, flip the mask before feeding it in.
CategoryPractical-Tools/Image

Inputs (14)

NameTypeDefaultDescription
textSTRINGtext
font_fileCOMBOPuHui.ttf1 options: PuHui.ttf
alignCOMBOcenter3 options: center, left, right
char_per_lineINT801–8096
leadingINT80–8096
font_sizeINT721–2500
text_colorSTRING#FFFFFF
stroke_widthINT00–8096
stroke_colorSTRING#FF8000
x_offsetINT00–8096
y_offsetINT00–8096
widthINT5121–8096
heightINT5121–8096
size_asopt*

Outputs (2)

NameTypeDescription
imageIMAGE
maskMASK