Nodes/ComfyUI Speech Bubble/Speech Bubble Overlay (吹き出し合成)
ComfyUI Node

Speech Bubble Overlay (吹き出し合成)

Your model still can't spell — so draw the speech bubble yourself

By miya805843·Created 2 days ago·Updated about 14 hours ago· 6
Speech Bubble Overlay (吹き出し合成)
  • image
  • image
◄textこんにちは! ComfyUIへようこそ!►
◄directionvertical►
◄bubble_typeellipse►
◄tail_directionbottom_left►
◄tail_length0.70►
◄pos_x0.50►
◄pos_y0.35►
◄font_nameURWGothic-Book►
◄font_size36►
◄text_color#000000►
◄bubble_color#FFFFFF►
◄border_color#000000►
◄border_width3►
◄bubble_opacity1.00►
◄padding24►
◄max_chars_per_line10►
◄line_spacing6►
◄opacity1.00►
◄thought_bump_size1.00►
◄seed0►

You got the manga panel you wanted. Then you look at the balloon the model drew and it says ホわウア ゴわフ, or nothing, or a very confident string of alien glyphs. Even Qwen-Image - the best text renderer going - gives you a font you didn't choose at a size you didn't choose. For specific words in a specific balloon, prompting is the wrong tool.

SpeechBubbleNode is the right one. It's the single node in a one-node pack by miya805843, and it composites an actual manga balloon with actual font glyphs onto your image after the sampler. No diffusion, no seed lottery, no re-rolling.

Why it exists: as of mid-2025 the answer on r/comfyui to "can I add speech balloons in ComfyUI?" was no, open Photoshop - one poster had given up searching entirely, because "ComfyUI + speech" keeps returning text-to-speech nodes.

What it actually draws

A typography node wearing a post-processing costume. Asking a diffusion model to generate letters is doing with a sampler what Pillow does in milliseconds. From the source, not the README: it builds a silhouette mask for the bubble shape, dilates it with a max-filter to lay down a seamless border, then pastes the fill colour through that same mask. Text is drawn separately, as real glyphs. Everything renders on a 2× supersampled canvas and downsamples with Lanczos - that's the smooth outlines.

Because border and text are separate from the fill, bubble_opacity does exactly what the author claims: drop the whites to 60% so hair shows through, and the dialogue and outline stay fully crisp. It's the setting that makes a bubble feel placed rather than pasted.

Four shapes: ellipse, rounded_rect (narration box), thought (cloud plus trailing dots), shout (spiky burst). The last two are procedural from seed - thought_bump_size plus a new seed gets you endless organic variants.

The inputs you'll actually touch

  • image - your tensor. VAEDecode, or an upscaler if you're finishing big.
  • text - multiline dialogue. Full-width spaces ( ) and blank lines are your indentation tools. Convert the widget to an input and you can feed it from an LLM instead.
  • direction - vertical (right-to-left columns) or horizontal. Defaults to vertical, which is the point of the pack.
  • bubble_type, tail_direction, tail_length - shape and pointer. tail_length: 0.0 means no tail.
  • pos_x / pos_y - the bubble's centre, normalized. The defaults (0.5, 0.35) land upper-middle, roughly where a face isn't.
  • font_name / font_size - where people get burned. See below.

The rest - three colour fields, border_width, padding, max_chars_per_line, line_spacing, thought_bump_size, opacity - is tuning. One output, image, at input resolution; the node isn't an output node, so keep a SaveImage on the end.

Install

Manager, search ComfyUI-Speech-Bubble. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/miya805843/ComfyUI-Speech-Bubble.git

Restart, done. requirements.txt asks only for Pillow>=9.5.0 and numpy>=1.23.0, both already in any working install, and torch is optional. No weights, no downloads. Against the dependency hell this ecosystem is notorious for, it's a holiday. It's MIT, version 1.0.0, packaged for the Comfy Registry - and new enough that you'd be an early adopter, so expect rough edges rather than polish.

Fonts are the whole job

font_name is built by scanning fonts/ inside the pack, then the OS font folders for Windows, macOS or Linux, reading each TrueType name table so you see 源暎アンチック v5 instead of yusei_magic.ttf. Three traps follow.

The list is whatever your machine has. On the box this node was indexed on, the default was URWGothic-Book - a Ghostscript font with zero Japanese coverage. Feed it kana and you get empty boxes; nothing's broken, the font can't draw them. Install a CJK font (fonts-noto-cjk or fonts-ipafont-gothic on Debian/Ubuntu) or drop a manga font into fonts/. Real manga type is antick style - 源暎アンチック and アンチックセシル are the ones the author names - and it beats Noto by a mile.

The scan is cached per process. Add a font file, then restart ComfyUI - refreshing the tab won't do it.

The font name travels inside the workflow. Open a Windows-built graph on Linux and the stored name doesn't exist there. Re-pick it. One click, if you know.

Where it bites

max_chars_per_line is a character count, not a width. Horizontal mode slices every N characters, so English breaks mid-word - write your own breaks and set N generously. Vertically it's characters per column; 10 is a sane manga default, but long lines stack into many columns and the balloon swallows the frame.

No bounds clamping. The balloon sizes itself to the text and centres on pos_x/pos_y; dialogue near an edge is cropped off the canvas.

It doesn't erase text the model already drew. If your panel came out with gibberish in a balloon, mask or inpaint that first. Clean pipeline: prompt for an empty balloon, then typeset.

In a batch the seed shifts per frame (the code adds the image index to seed), so each thought bubble varies. Lovely for variety, wrong for a consistent multi-panel sequence - run those one at a time, seed pinned.

Set it up once with a good CJK font and it stops being a node you think about - just the step before SaveImage, doing the one thing a 20-billion-parameter model is still worse at than a forty-year-old typesetting tradition.

Categoryimage/postprocessing

Inputs (21)

NameTypeDefaultDescription
imageIMAGE—
textSTRINGこんにちは! ComfyUIへようこそ!—
directionCOMBOvertical2 options: vertical, horizontal
bubble_typeCOMBOellipse4 options: ellipse, rounded_rect, thought, shout
tail_directionCOMBObottom_left5 options: bottom_left, bottom_right, top_left, top_right, none
tail_lengthFLOAT0.700–3—
pos_xFLOAT0.500–1—
pos_yFLOAT0.350–1—
font_nameCOMBOURWGothic-Book47 options: C059-BdIta, C059-Bold, C059-Italic, C059-Roman, D050000L, DejaVu Sans, +41
font_sizeINT368–256—
text_colorSTRING#000000—
bubble_colorSTRING#FFFFFF—
border_colorSTRING#000000—
border_widthINT30–30—
bubble_opacityoptFLOAT1.000–1—
paddingoptINT240–200—
max_chars_per_lineoptINT101–100—
line_spacingoptINT60–50—
opacityoptFLOAT1.000–1—
thought_bump_sizeoptFLOAT1.000.2–3—
seedoptINT00–18446744073709550000—

Outputs (1)

NameTypeDescription
imageIMAGE—