XB-BOX - 🖌️ ShenBi Brush
A drawing pad that lives inside your ComfyUI graph
- Image
Every "draw your own input" workflow eventually hits the same wall: getting a picture into the graph. The stock route is Load Image → right-click → Open in Mask Editor, which paints masks, not pixels. The other route is round-tripping through Krita or Photoshop, which works but means leaving the tab. ShenBi ("magic brush") is the blunt answer - a node with no input sockets at all and a paint board baked into it.
What it actually is
One node, two modes, and the mode values are Chinese in the widget:
- 创作 (Create) - a blank white or black canvas; the output is forced to exactly your width × height.
- 编辑 (Edit) - pick an image from ComfyUI's input folder (same dropdown and upload button as stock Load Image), draw over it, send the result downstream.
No layers, no spot-heal, no documents - it's a pad, and honest about being one. What it buys you is timing: rough out a composition by hand, then let a scribble ControlNet or an edit model finish it. Scribble exists precisely for "doodle in, detailed image out," and doing it inside the graph removes the file juggling that usually kills the habit.
How the painting works
The painting is all front-end, in a modal the node opens (js/xb_shenbi.js); Python only loads and sizes images. You get brush size 1–300 px, eleven swatches plus a color picker, an eraser, flips, 90° rotation, undo/redo, and clear. Ctrl+S saves.
Saving is the interesting bit. The board is POSTed as a PNG to input/xb_shenbi/xb_shenbi_<node id>_<mode>.png - the same /upload/image route the official mask editor uses - and the widget keeps only the filename. That's deliberate and correct: a 1024² PNG is about 1.7 MB, and inline it as base64 and a 2 KB workflow JSON becomes megabytes, blows the browser's draft quota, and you lose the graph on refresh. The two modes keep separate boards (created_data for Create, painted_data for Edit), both marked "internal field, don't hand-edit."
aspect_ratio drives width/height on a 32-step grid (1:1, 16:9, 9:16, 4:3, 3:4, 21:9, or Free). Create mode snaps output to that target and cover-crops, so no letterboxing. Edit mode is asymmetric: a source bigger than the target is scaled down and centre-cropped, a smaller one is left alone and never upscaled. A very large blank board is painted at reduced size (long side capped at 4096) and scaled back up on the backend - handing a browser several 8K canvases is how you kill the tab.
Inputs and output
You'll set mode, aspect_ratio, width/height (1024² by default, up to 16384), and canvas_color - the Create background, and also what Edit mode hands you when the source file can't be read. image is the Edit-mode source from input/; missing or renamed, the node warns and gives you a plain canvas rather than failing, because its VALIDATE_INPUTS deliberately returns True. Leave painted_data and created_data alone.
One output: Image, a single IMAGE tensor at ComfyUI's intermediate dtype and device, same as stock Load Image. It isn't a latent, so for img2img you still need a VAE Encode in front of the sampler.
Installing it
ComfyUI Manager → search XB_ToolBox → install → restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/wjluoxiao/XB_ToolBox.git
# restart ComfyUI
Don't believe the README's "no extra pip dependencies required! Plug and play." The source disagrees: __init__.py imports nodes_audio_slicer unguarded, that file imports PyAV (av) at its top, and the CosyVoice3 imports are unguarded too. Without them the pack throws an ImportError on load - and since every node registers in one block, ShenBi goes down with it. Let the Manager install from requirements.txt, or run it yourself; none of that list is needed by ShenBi, which runs on PIL, numpy and torch that ComfyUI already ships.
Common issues
- Node missing after restart. Look for an ImportError from this pack in the console - it's the dependency situation above.
- Editor won't open, or opens blank. The front end probes the 2D canvas first (fills a pixel, reads it back) because a broken GPU-accelerated canvas returns transparent pixels without ever throwing. Enable browser hardware acceleration.
- "I changed the resolution and nothing happened." Once painted, the Create board is locked to its own size - hit 🗑️ 删除画布 (two clicks; the first arms it) to reset it to the current target.
- You repainted and the output is stale. The classic canvas-node bug: the widget value never changes, because only a filename is stored and the file is overwritten in place. This pack fingerprints the board's mtime and size in
IS_CHANGED, so a repaint does force a re-run. On a very old build, update.
Verdict
Drawing inside ComfyUI is a genuinely wanted thing - canvas and paint nodes are a recurring pitch, and the bigger ones get real traction. ShenBi is the lightweight take: one pad, two modes, sizing rules that do what you'd expect. If your flow is "sketch a layout, let the model flesh it out," it's the shortest path. Budget five minutes for the Chinese labels - 创作 is Create, 编辑 is Edit, and the button above the preview says 🎨 创作画布.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | 创作 | 创作 = 纯色画布作画;编辑 = 在本地图片上作画 |
| aspect_ratio | COMBO | Free | 画幅比例,与宽高联动(步长 32) |
| width | INT | 102432–8192 | 目标宽度,对齐 32 的倍数(32 ~ 8192) |
| height | INT | 102432–8192 | 目标高度,对齐 32 的倍数(32 ~ 8192) |
| canvas_color | COMBO | 白色 | 创作模式的纯色画布颜色 |
| image | COMBO | 编辑模式加载的本地图片 | |
| painted_data | STRING | 内部字段:编辑模式画板的 PNG(base64) 存档,勿手工修改 | |
| created_data | STRING | 内部字段:创作模式画板的 PNG(base64) 存档,勿手工修改 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Image | IMAGE | — |