Raster To Uniform SVG
Raster to vector with uniform strokes — the node that makes pixelated diagrams worth scaling
- image
- svg_string
- svg_path
- preview_image
A scanned or generated diagram is a grid of pixels, which means its lines are jagged, blurry, and variable in width - useless if you want to scale it, engrave it, or feed it to anything that expects clean geometry. Raster to Uniform SVG traces the linework and emits a real SVG where every stroke is the same width, so a 1-pixel-wobbly line becomes a crisp, even vector path. The "Uniform" in the name is the whole pitch: it doesn't just vectorize, it normalizes line weight.
How it works
Convert to grayscale, binarize (with threshold in 0–255; leave it at 0 and it uses Otsu's automatic threshold, which is the right call for most input), skeletonize down to 1px lines, then trace paths through the skeleton and write each as an SVG <path>. The line_width float (0.5–10, default 2) sets the uniform stroke width, stroke_color (default "black") sets the stroke, and invert_colors flips which side counts as line. transparent_background (default on) omits the background rect entirely - if you want a white backing, turn it off.
The SVG is written to your ComfyUI output directory under filename_prefix (default "diagram"), using folder_paths.get_output_directory().
What comes out
svg_string(STRING) - the full SVG markup, if you want to pipe it into another node.svg_path(STRING) - the file path where the SVG was saved, for downstream tools that want a file.preview_image(IMAGE) - a raster preview of the result so you can check the conversion visually without opening the file.
The svg_path is the one to wire into whatever consumes files - and the preview is your QA pass.
Where it fits
The classic chain: Load Image → Extract Black → DashedToSolidLine → RasterToUniformSVG. Clean the linework first and the vector output inherits that cleanliness. From here the SVG can go to a laser-cutter software import, an engraving workflow, or anywhere that wants uniform-stroke vector art. It also composes with the pack's SVG measurement nodes - SVGDimensions and SVGPathLength - which accept SVG strings, so you can vectorize and then measure the result in one graph.
Install
Part of ComfyUI-HappNodeSet (mikemojen). ComfyUI Manager: search HappNodeSet. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/mikemojen/ComfyUI-HappNodeSet.git
pip install -r ComfyUI-HappNodeSet/requirements.txt
Restart ComfyUI. It needs svgwrite (in the requirements) for the SVG generation, plus skimage for skeletonization. Note cairosvg is listed in the pack's requirements as "Optional: for SVG preview rendering" - if previews fail to render, that's the package to install; everything else works without it.
Common issues
The output quality is gated by the skeletonization, so thick or noisy linework produces lumpy paths - thin the input first. threshold at 0 (Otsu auto) is a good default but will be wrong on very unbalanced images (mostly white, tiny black marks), where manual thresholds shine. And if the preview looks right but the file is missing, check filename_prefix for characters your OS hates. One more: this node only takes the first image in a batch - feed it a single image, not a stack, or only the first frame converts.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| line_width | FLOAT | 2.00.5–10 | — |
| filename_prefix | STRING | diagram | — |
| thresholdopt | INT | 00–255 | — |
| stroke_coloropt | STRING | black | — |
| invert_colorsopt | BOOLEAN | false | — |
| transparent_backgroundopt | BOOLEAN | true | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| svg_string | STRING | — |
| svg_path | STRING | — |
| preview_image | IMAGE | — |