转换图像丨SVG
Turn a raster into vector paths — without leaving ComfyUI
- image
- mask
- svg_content
- width
- height
- mask
- preview
Some jobs in ComfyUI are about making images. Others are about getting an image out of pixel-land and into a vector format - for laser cutting, vinyl, print at any size, or a logo you want to be infinitely zoomable. ImageToSVG is the QING pack's answer: it takes an image tensor, traces it into SVG path markup, and hands you the raw SVG as a string, plus a preview so you can see what you're actually going to get.
It's from ComfyUI-QING (display name "转换图像丨SVG"), and it's one of three SVG nodes in the pack - LoadSVG brings SVG text in, SVGSaver writes it out to disk.
How it works
The tracing itself is done in pure Python - cv2 for edge detection, numpy/PIL for processing, and an XML builder to assemble the path data. No GPU, no model, no cairosvg required for this direction (cairosvg is what the pack uses for the reverse direction, SVG→PNG). Four conversion modes pick the flavor of tracing:
edge_detection(default) - Canny-style edge tracing, good for line art and sketches.color_quantization- flattens colors and traces regions, good for flat-color illustrations.silhouette- solid filled shape from a threshold, good for stencils.posterize- poster-style color bands.
The tuning knobs are the ones you'd expect from any vectorizer: precision (1–200, detail level), simplify_tolerance (higher = smoother, fewer points), min_area (drop tiny specks), and the two edge_threshold* values for edge mode. There's also a preset dropdown - simple / detailed / artistic / custom - that pre-fills those knobs so you don't have to learn them all at once. Optional extras: a mask to limit tracing to a region, stroke color/width for edge output, a background_color for the preview, and minify_svg to compact the output.
Outputs: svg_content (the SVG markup as a string), width/height INTs, mask, and preview (an IMAGE so you can look at the result in the graph).
The honest take
Auto-tracing is never as clean as a human with a pen tool, and this node is no exception. For a silhouette or simple flat-color shape, the results are genuinely usable - stencil-ready. For a photograph, you'll get a jagged approximation that's only useful as an artistic effect. The presets matter: start with simple and ratchet up precision only if the output is too crude, because high precision on a complex image produces SVG files with tens of thousands of path points that nothing downstream will enjoy. Where people get burned: feeding it a busy photo and wondering why the SVG is 40MB. Trace at the resolution you need, not the resolution you have.
Since it outputs a string, remember the next step is either the pack's SVGSaver (write to file) or SVGToImage (rasterize back to PNG/JPG) - the raw markup just sitting in a STRING socket isn't going to do anything by itself.
Installing
Part of ComfyUI-QING - install the pack, get all three SVG nodes plus the rest. ComfyUI Manager: search "ComfyUI-QING". Or:
cd ComfyUI/custom_nodes
git clone https://github.com/GAO-SHIQING/ComfyUI-QING
cd ComfyUI-QING
python install_dependencies.py # or: pip install -r requirements.txt
Restart ComfyUI. Deps: Pillow, opencv-python, scipy, scikit-image, cairosvg. cairosvg is listed in requirements and is what the pack recommends for best SVG→image rendering - worth keeping installed even though this node doesn't need it. No model downloads. China mirror: --mirror --auto. Python ≥ 3.9.
Gotchas
The edge_threshold1/edge_threshold2 pair behaves like any Canny threshold: lower them to catch faint edges, raise them to ignore noise - with auto-threshold on by default (edge_auto_threshold) the node picks values for you, which is usually right. simplify_tolerance is your best lever for file size: bump it and the SVG gets dramatically smaller at the cost of fine detail. And when a trace comes out empty or garbled, the first suspect is a too-high min_area wiping out every region. Start low, work up.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| conversion_mode | COMBO | edge_detection | 4 options: edge_detection, color_quantization, silhouette, posterize |
| precision | INT | 1001–200 | — |
| preset | COMBO | simple | 4 options: custom, simple, detailed, artistic |
| edge_threshold1 | INT | 501–200 | — |
| edge_threshold2 | INT | 1501–300 | — |
| simplify_tolerance | FLOAT | 1.00.1–10 | — |
| min_area | INT | 101–1000 | — |
| maskopt | MASK | — | |
| edge_auto_thresholdopt | BOOLEAN | true | — |
| preserve_aspect_ratioopt | BOOLEAN | true | — |
| background_coloropt | STRING | #FFFFFF | — |
| stroke_coloropt | STRING | #000000 | — |
| stroke_widthopt | FLOAT | 1.00.1–10 | — |
| silhouette_auto_thresholdopt | BOOLEAN | true | — |
| silhouette_thresholdopt | INT | 1270–255 | — |
| preview_max_sizeopt | INT | 51264–2048 | — |
| minify_svgopt | BOOLEAN | true | — |
| decimal_precisionopt | INT | 20–6 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| svg_content | STRING | — |
| width | INT | — |
| height | INT | — |
| mask | MASK | — |
| preview | IMAGE | — |