Illustrious Comic Lettering - 4 Panel
Deterministic speech bubbles for 2×2 comic pages
- image
- lettered_page
- bubble_mask
If you've ever generated a comic page and squinted at the dialogue, you know the problem: the art comes out fine, but the lettering is misspelled, duplicated, half Japanese glyphs, or stacked on top of the previous panel's text. Diffusion models are great at suggesting text and terrible at writing it. IllustriousComicLettering4Panel is the pragmatic answer - it stops trying entirely. After VAE Decode, it draws real font-rendered dialogue into clean speech bubbles with Pillow. Deterministic, no hidden API, no model download, no randomness. The image model makes the comic; this node types the words.
People have been hand-rolling this in GIMP and Clip Studio since the earliest speech-bubble posts on r/StableDiffusion, because nobody wanted to burn a diffusion pass on spelling. This node is that work as a graph node.
What it actually does
It takes a decoded image and splits it into a fixed 2×2 grid using outer_margin (page border) and gutter (space between panels). For each panel it draws an ellipse bubble, wraps your text, and if the text won't fit, keeps shrinking the font from font_size down to min_font_size until it does. The bubble sits opposite the speaker: pick left, right, or center per panel in panel_1_speaker … panel_4_speaker, and the tail points back toward them. Clever bit in the source: bubble position is rule-based, not face detection - so if a character's face is on the wrong side, flip the dropdown rather than fighting the layout.
Only the inputs that matter for a beginner:
panel_1_text…panel_4_text- the actual dialogue. Keep it to 4–7 words per panel; that's the range where the auto-fit stays legible.panel_1_speaker…panel_4_speaker-left/right/centerbubble placement.font_name- defaults toDejaVuSans-Bold.ttfand falls back through Arial and Liberation if missing, so a broken font path is rarely fatal.fill_color/border_color/text_color- hex strings, defaults are white bubbles with near-black text.
The geometry knobs (padding, panel_safe_margin, border_width, outer_margin, gutter) are fine to leave alone until something looks cramped.
Outputs are lettered_page (the finished IMAGE - wire it into a Preview or Save Image node) and bubble_mask (a MASK of exactly where the bubbles went). The mask is the useful one: pipe it into an inpaint pass to clean up old text the bubble doesn't cover, or use it for compositing. Batch input is supported, so a whole page of comics renders in one queue.
Installing it
ComfyUI Manager may find it as "Illustrious Comic Lettering," but the repo's pyproject.toml still carries placeholder publisher fields, so if Manager comes up empty, clone it directly:
cd ComfyUI/custom_nodes
git clone https://github.com/katorikonoe-ai/ComfyUI-IllustriousComicLettering.git
cd ComfyUI-IllustriousComicLettering
pip install -r requirements.txt
Restart ComfyUI. The requirements are just Pillow>=10.0 and numpy>=1.24 - no torch-heavy extras, no model files, nothing to hunt down. The node appears under Illustrious Comic/Lettering. It says "Illustrious" because the author designed it around Illustrious XL comic workflows, but it sits after VAE Decode and works after any checkpoint that can draw a page.
Where people get burned
The big one, straight from the README: if the generated art already contains text, this node cannot erase it. It draws over pixels; it doesn't understand them. Regenerate with a text-free negative prompt, inpaint the old lettering, or make the opaque bubble big enough to swallow it. That's what the bubble_mask is for.
Relatedly, the prompting rule matters more than any widget here. You want the model to leave clean negative space in each panel - put "no text, no dialogue, no subtitles" in the negative and something like "clear empty space near the top corner of every panel for later lettering" in the positive. The node assumes your page actually has that clean 2×2 grid, because it computes panel boxes from margins, it doesn't detect them. Feed it a page with a 3-panel top row and bubbles will land in the wrong places.
Also worth knowing its limits up front: fixed 2×2 only, one bubble per panel, horizontal Latin-script text only. It's a tool, not a letterer - it won't kern dialogue or do manga sound effects. But for readable, deterministic dialogue on finished pages, it's the fastest thing that works.
A fresh v1.0.0 pack (August 2026) with zero community footprint yet - treat any rough edges as new-software roughness and file issues on the repo.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| panel_1_text | STRING | One last seed. | — |
| panel_2_text | STRING | Grow strong. | — |
| panel_3_text | STRING | Take your time. | — |
| panel_4_text | STRING | You made it. | — |
| panel_1_speaker | COMBO | 3 options: left, right, center | |
| panel_2_speaker | COMBO | 3 options: left, right, center | |
| panel_3_speaker | COMBO | 3 options: left, right, center | |
| panel_4_speaker | COMBO | 3 options: left, right, center | |
| font_size | INT | 4212–180 | — |
| min_font_size | INT | 208–96 | — |
| padding | INT | 284–160 | — |
| outer_margin | INT | 450–512 | — |
| gutter | INT | 240–256 | — |
| panel_safe_margin | INT | 260–256 | — |
| border_width | INT | 40–24 | — |
| fill_color | STRING | #FFFFFF | — |
| border_color | STRING | #111111 | — |
| text_color | STRING | #111111 | — |
| font_name | STRING | DejaVuSans-Bold.ttf | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| lettered_page | IMAGE | — |
| bubble_mask | MASK | — |