Schematic Overlay
Turn any render into annotated technical data-art — one node, no model, no API
- image
- pixelate_mask
- texture
- texture_mask
- image
- overlay_only
- overlay_alpha
You know the look: a photo drained into white-on-dark, then buried under detection circles, dashed crosshairs, connection lines, coordinate labels and little pixelated zones - like a page torn out of a technical manual. ComfyUI can prompt that aesthetic into a generation, but it comes out half-baked, with gibberish labels and wobbly geometry. Schematic Overlay is the deterministic route: it takes an image you already have and draws the whole annotation apparatus over it in one node. No model, no API key, nothing to download besides the pack - it runs on Pillow, which is CPU-only and fast.
This is a post-processing node, not a generator. It sits at the end of a workflow, after VAE decode: feed it the render (or photo) you actually like, and it stylizes it into "technical data-art" while never touching the pixels outside its own overlay marks. If you want product renders to read as engineering documentation, or a logo shot as a "strategy diagram," this is the fastest route that doesn't involve retraining anything.
How it works
The engine is a grid analysis. The image is split into block_size squares (default 16px), each block gets a score, and blocks above threshold become circle candidates. The detection_mode picks the scoring: combined (the default) multiplies contrast by brightness deviation; contrast, bright, and dark each score a single measure. max_circles caps how many get placed and min_distance enforces spacing so they don't cluster - the whole thing is the classic "detected features on a technical plate" illusion. Circle size is driven by the detection score (between min_radius and max_radius) plus a seeded jitter, so seed changes the distribution of sizes without moving the centers.
Then the ornamentation layers stack on. connection_dist draws straight lines between every pair of circles within that range (set it to 0 to hide lines). The chain_* inputs draw a tangent chain of circles radiating from the canvas center with a shrinking or growing radius per step, plus optional intersection markers with coordinate labels. The crosshair_* group is the dashed full-canvas cross, the dashed centered square frame, and a center asterisk. Pixelation zones get placed either from a coordinate string (pixelate_zones as "x,y;x,y") or from a mask - each connected white region's centroid becomes a zone center. An optional texture image is screen-blended over the whole canvas (if you leave it unplugged and texture_opacity is above zero, a seeded procedural grain fills in), and the four frame_text_* corners give you the studio-slate label look.
The inputs that matter
image- the source photo. Required, and it's the only input you truly can't live without.detection_mode,threshold,max_circles,min_distance- the four knobs that decide whether the circles look like a sparse, confident diagram or a dense cloud.seed- reseed the circle-size jitter and the grain fallback. Deterministic per seed.palette- four built-ins (whiteOnDark,blackOnLight,goldOnDark,greenOnDark) pluscustom, which turns on thebg_color/stroke_colorhex pair. Note that custom only applies whenpaletteis set tocustom.size_preset- match the input, or cover-fit (crop-to-fill, centered) into fixed presets like Square, Landscape 16:9, or Instagram Story. Handy when you're templating for a social slot.
Outputs and where they wire
Three outputs, all from the pack's shared pipeline:
image- the full composite: background, photo, pixelation, crosshair, connections, circles, frame text, texture, chain, in that order.overlay_only- the same stack with the photo removed, so the vector layer can be composited onto anything else.overlay_alpha- a 0-to-1 MASK of everywhere a vector element (crosshair, connections, circles, frame text, chain) was drawn. Handy for downstream masking - say, only grain or darken the annotated areas.
Install
Via ComfyUI Manager (search "ComfyUI Schematic"), or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Schematic
Restart ComfyUI and both nodes show up under AKURATE/Schematic. The only declared dependency is Pillow>=9.0, which ComfyUI already ships - so no model downloads and no pip side-show. (Schematic Voronoi in the same pack uses scipy, but scipy ships with ComfyUI too.)
Where people get tripped up
The pack is new (first commit August 2026), so there's no backlog of community war-stories - but the grounded gotchas are worth knowing. Circles coming out too sparse? Drop threshold or raise max_circles. Lines everywhere? That's connection_dist - set it lower, or 0 to disable. Want your custom colors to actually show? palette must be custom. And if you're batching video frames, the texture input uses frame 0 for every frame - a per-frame texture won't animate, so connect one or accept the grain fallback. One genuinely nice touch: the same seed produces the same plate every run, so you can tweak one widget and get exactly one clean change.
Inputs (46)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| detection_mode | COMBO | combined | Circle placement scoring mode. Combined = contrast x brightness deviation (default). Contrast, Bright, Dark score blocks by that single measure. |
| block_size | INT | 168–64 | Analysis grid resolution - smaller = more detail |
| threshold | INT | 300–80 | Min score to place a circle - higher = fewer, stronger hits |
| max_circles | INT | 8020–400 | Cap on total circles placed |
| min_distance | INT | 4010–200 | Spacing between circle centers - prevents clustering |
| shape | COMBO | circle | Detection circle outline shape |
| min_radius | INT | 41–40 | Smallest circle size (low-score regions) |
| max_radius | INT | 244–120 | Largest circle size (high-score regions) |
| circle_stroke | FLOAT | 1.00.1–8 | Circle outline thickness |
| seed | INT | 420–4294967295 | Random seed for size variation - change for different distributions |
| label_size | INT | 84–48 | Font size of x,y coordinate labels |
| overlay_opacity | FLOAT | 1.000–1 | Master opacity for all circles, lines, dots, and text |
| connection_dist | INT | 1500–500 | Circles within this range get connected - 0 hides lines |
| line_weight | FLOAT | 0.80.1–8 | Thickness of connecting lines |
| chain_enabled | BOOLEAN | true | Enable the tangent chain of circles radiating from canvas center |
| chain_count | INT | 110–40 | Number of circles in the chain |
| chain_angle | INT | 450–90 | Direction of chain - 0 vertical, 45 diagonal, 90 horizontal |
| chain_base_radius | INT | 25020–1000 | Size of the center circle |
| chain_ratio | FLOAT | 0.790.3–1.2 | Size multiplier per step - below 1 shrinks outward |
| chain_intersections | BOOLEAN | true | Draw intersection markers where consecutive chain circles overlap |
| chain_intersection_size | FLOAT | 5.00.5–20 | Dot size at each adjacent-circle intersection |
| crosshair_enabled | BOOLEAN | true | Enable the dashed crosshair, frame square, and center asterisk |
| crosshair_frame_size | INT | 6010–100 | Square size as % of canvas short side |
| crosshair_dash | INT | 81–40 | Length of each dash + gap |
| crosshair_stroke | FLOAT | 1.00.1–8 | Line thickness for frame and crosshair |
| crosshair_star_size | INT | 400–300 | Diameter of the center asterisk - 0 hides it |
| crosshair_star_points | INT | 42–12 | Number of crossing lines - 2 is a plus, 4 is an 8-pointed star |
| pixel_size | INT | 161–80 | Mosaic block size - larger = blockier |
| zone_size | INT | 10010–500 | Half-width of each square pixelation zone |
| pixel_stroke | BOOLEAN | true | Draw an outline around each pixelation zone |
| image_opacity | FLOAT | 0.850–1 | Fade the background image |
| texture_opacity | FLOAT | 0.500–1 | Opacity of the noise overlay (screen blend) |
| frame_text_size | INT | 126–72 | Font size of the 4 corner labels |
| frame_text_tl | STRING | Design & Strategy | Top-left corner frame text |
| frame_text_tr | STRING | AKURATE | Top-right corner frame text |
| frame_text_bl | STRING | Bottom-left corner frame text | |
| frame_text_br | STRING | Bottom-right corner frame text | |
| palette | COMBO | whiteOnDark | Color palette for background and stroke color |
| size_preset | COMBO | match input | Canvas size. 'match input' keeps the source image dimensions; presets cover-fit (crop-to-fill, centered) the source before resizing |
| bg_color | STRING | #0a0a0a | Custom palette background color (hex). Used when palette = custom |
| stroke_color | STRING | #d8d8d8 | Custom palette stroke color (hex). Used when palette = custom |
| pixelate_zones | STRING | Pixelation zone centers as 'x,y;x,y;...' in canvas pixels. Union with pixelate_mask centroids | |
| pixelate_maskopt | MASK | Optional mask; each 8-connected white region's centroid becomes a pixelation zone center | |
| textureopt | IMAGE | Optional texture/noise image, screen-blended over the canvas. If empty and texture_opacity > 0, a procedural grain fallback is used | |
| texture_maskopt | MASK | Continuous modulator for the texture screen blend; white = full texture, black = none; frame 0 used for batches |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| overlay_only | IMAGE | — |
| overlay_alpha | MASK | — |