NanoBanana Text Mask
Type a word, get a hidden-text mask — no image editor required
- image
- mask
Most hidden-text workflows start in an image editor: make a black canvas, type white text, export a PNG, load it into ComfyUI. That round trip is silly, and this node exists to kill it. Feed it a string and it renders a centered, multiline text image and a matching mask on the spot - no Photoshop, no file juggling, nothing to keep in sync between versions of your word.
If you've seen this pack's pattern preprocessor, think of this node as the no-assembly version of the same idea for text. The preprocessor cleans up art you bring in; Text Mask generates clean art from nothing. The output is already crisp black-and-white, so you can feed it straight to a ControlNet and skip preprocessing entirely.
How it works
Under the hood it's a PIL text render. The node makes a solid canvas at your width x height, centers your text (with margin padding) using multiline_text, and returns it twice - once as an RGB image, once as a mask. The invert toggle flips background and foreground, so you can emit white-text-on-black or black-text-on-white without leaving the node.
One thing worth knowing: the font loader tries DejaVuSans-Bold, then Arial Bold, then Arial, and falls back to Pillow's tiny default bitmap font if none exist. On a normal desktop install you'll get a bold sans and never think about it. On a minimal headless Linux box you can end up with the default font, which is why font_size goes up to 1024 - you can compensate, but a real font is better.
Inputs that matter
- text (default "NANOBANANA") - multiline, so
ART\nIS\nFREEbecomes three lines. Blank input falls back to the default. - font_size (default 180) and margin (default 64) - the two knobs that actually control how big the hidden message is relative to the canvas.
- width / height - set these to match your generation resolution. Defaults are 1024, which suits SDXL and FLUX; drop to 512-ish territory for SD 1.5 if your latent is smaller.
- invert - polarity flip for whatever ControlNet you're driving.
Outputs: image (the rendered text, white-on-black by default) and mask (same thing as grayscale). image goes into your ControlNet; mask is there when you want to use the text as conditioning region or a latent mask in the FLUX ghost path.
Installing it
Part of the ComfyUI-HiddenImages pack, same install as its siblings: ComfyUI Manager, search "ComfyUI-HiddenImages", or clone into custom_nodes and run ./install.sh. The node itself needs nothing beyond Pillow - the pack's text preset installs the ControlNet weights and helper nodes it's meant to pair with.
Gotchas
The obvious one is resolution mismatch: a 1024px mask feeding a 512px latent is asking for trouble, and a text render scaled down later loses its crisp edges. Match canvas size to the latent from the start. And keep the name collision in mind while you search - "NanoBanana" here is just the pack's branding, unrelated to Google's Gemini image model of the same name (and to a certain scam domain selling credits for it). These nodes call no API and need no key; everything happens in Pillow.
If your text comes out looking like a glyph soup or gets clipped, it's the font fallback or the margin, in that order. Otherwise this is the most painless node in the pack - type, wire, done.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | NANOBANANA | — |
| width | INT | 1024128–4096 | — |
| height | INT | 1024128–4096 | — |
| font_size | INT | 18012–1024 | — |
| margin | INT | 640–512 | — |
| invert | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |