Image to Centerline SVG
Image to Centerline SVG
- image
- svg_string
This is the node that gives the whole pack its point. Pen plotters don't draw pixels - they draw lines, one continuous stroke at a time. Feed a normal ComfyUI image into Image to Centerline SVG and it traces the linework down to a single-pixel-wide skeleton, then emits that skeleton as a vector SVG you can plot. If you've ever tried to plot a raster drawing and watched the pen wander over thick, doubled-up outlines, you know why this matters: a pen can only follow the middle of a line, and this node finds the middle for you.
It's the entry point of the classic pipeline: generate or load an image → ImageToCenterline → Optimize SVG with vpype → Plot SVG with AxiDraw (or SVG to Submission File → Upload). Dark lines on a light background work best, which is exactly what most line-art generations produce.
How it works
Four steps under the hood, all grounded in the code. The image tensor is converted to OpenCV format and inverted, so your dark lines become white on black. That binary image goes through a thinning pass - Zhang-Suen skeletonization, or scikit-image's skeletonize if it's importable - that strips each line down to a one-pixel-wide centerline. Then a tracing routine (a port of Lingdong Huang's well-known skeleton-tracing algorithm, MIT-licensed and vendored into the pack) walks the skeleton and breaks it into polylines. Finally those polylines are stitched into a single <path> inside an SVG, colored by the color input (default black), and returned as svg_string.
The image input is your raster. color sets the stroke color of the output path. And optimize_exhaustive (default on)? Here's the honest part: in the shipped code it's accepted but doesn't actually branch anything - the tracing parameters are hardcoded. Don't burn time toggling it and expecting different output.
How to get good results
- Give it clean line art. Strong contrast, thin strokes, no fill. Thick blobby shapes skeletonize into weird spidery skeletons.
- Output goes straight into Optimize SVG with vpype for layout and line-merging before anything plots it - the raw skeleton is full of tiny segments, and that's expected.
- Watch the size. The skeleton is traced at the image's native resolution, so a huge image makes a huge SVG. Resize down first unless you actually want every pixel of detail.
Install
It's the flagship node of the ComfyUI PenPlotter pack. ComfyUI Manager → search "ComfyUI PenPlotter", or:
cd ComfyUI/custom_nodes
git clone https://github.com/wouterverweirder/comfyui-penplotter
Restart ComfyUI. This node specifically needs numpy, opencv-python and numba (the skeleton tracing is JIT-compiled with numba), which the pack installs alongside vpype, websockets, requests, qrcode[pil] and the AxiDraw API.
Common issues
- "Error: ..." as the output string - this node is unusual in that it returns error text as the SVG string instead of throwing. If your
svg_stringstarts with "Error:", something in the tracing failed; check the console for the real exception. - Skeleton looks broken or noisy - the input needs to be a clean binary-ish line drawing. Run thresholding, denoise, or a posterize step upstream before you trace.
- The
optimize_exhaustiveflag does nothing - correct, in the current version. It's vestigial; leave it on and move on.
For a niche pack this node is genuinely good at its one job. If you plot AI-generated line art, it's the reason to install the whole thing.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| optimize_exhaustiveopt | BOOLEAN | true | — |
| coloropt | STRING | black | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| svg_string | STRING | — |