png2svg
Agent-guided PNG to SVG reconstruction for logos, icons and monograms.
png2svg recovers the geometry and paint a designer would have used. It measures the raster at subpixel precision, builds a small parametric model, renders it and scores the result against the source. The finished SVG uses native paths and gradients with no embedded raster.
The project uses an agent-guided reconstruction workflow. It does not run as a one-shot converter. Shape decomposition, overlap and intentional design constraints still need visual judgment.
| Included example | Result | Construction |
|---|---|---|
| Keep | IoU 0.9966, edge 0.146px, 57 nodes, 1,284 B | overlapping fitted primitives |
| IN monogram | IoU 0.9976, edge 0.099px, 26 nodes, 710 B | measured polygons and clean watermark removal |
| P Auto | IoU 0.9988, edge 0.067px, 33 nodes, 852 B | one contour with a real plug cutout |
Install the skill
npx skills add iannuttall/png2svg
The skill bundles its own measurement and SVG engine. Its scripts use uv
to create a cached environment on first run, so nothing is installed into
the project being worked on.
Requirements:
- Python 3.12 or newer
- uv
Ask the agent to vectorise a logo and point it at a PNG or WebP file.
How reconstruction works
The agent drives the visual decisions. The library makes each measurement, model and SVG reproducible.
- Inspect the source and decide whether it is suitable.
- Decompose the artwork into shapes, overlaps and paint regions.
- Trace a designed outline or fit the primitives that created it.
- Recover flat colours, gradients and shape-following ramps.
- Render the SVG and compare it with the source at 50% opacity.
- Read residual clusters, adjust the model and repeat.
- Validate every output profile and export the final SVG.
There is no universal algorithm for deciding whether two meeting edges form a fillet, an overlap or a coincidence. That judgment is the point of the agent loop. Once the decomposition is chosen, the measurement and export paths are deterministic.
Run the included examples
Only Keep, IN and P Auto are published. Their source images are under
examples/assets/; the artwork notice explains
their separate licensing.
Keep
uv run png2svg init examples/assets/keep.png --project work/keep
uv run python examples/build_keep_model.py
uv run png2svg check work/keep
uv run png2svg export work/keep -o work/keep/generated/keep.svg
This example fits three disconnected groups as repeated rounded rectangles, clipped diagonal arms and a separate arrow. The soft shadow and low-level texture are deliberately left out.
IN monogram
uv run png2svg init examples/assets/in.webp --project work/n
uv run python examples/measure_n.py
uv run python examples/build_n_model.py
uv run png2svg check work/n
uv run png2svg export work/n -o work/n/generated/in.svg
This example measures straight edges and fitted corner cubics. A watermark in the source is treated as an artifact instead of being baked into the SVG.
P Auto
uv run png2svg init examples/assets/p-auto.png --project work/p
uv run python examples/measure_p.py
uv run python examples/build_p_model.py
uv run png2svg check work/p
uv run png2svg export work/p -o work/p/generated/p-auto.svg
The plug is negative space connected to the outside of the P. Keeping it in
the same contour makes the cutout work over any background. The optional
examples/build_plug_icon.py script writes standalone plug variants under
work/p/generated/.
Other artwork used during development stays in the ignored work/
directory. Generated SVGs belong there too, which keeps private sources and
build artifacts out of the repository.
What the checks measure
silhouette_ioumeasures overlap between the source and render masks.edge_dist_mean/p95/maxmeasures symmetric boundary distance in pixels.deltaE_mean/p95/maxmeasures CIEDE2000 over interior pixels.mae_linear_rgbreports mean absolute error in linear RGB.texture_stdestimates local texture in the source.deltaE_lowfreq_mean/p95scores structure and shading after removing grain.
check renders at 4x and downsamples by default. This reduces the
quarter-pixel edge quantisation of the SVG renderer. A correct edge near a
mask threshold can otherwise flip a full pixel row and make the model look
worse than it is.
Each check writes a comparison folder containing the reference, render, 50/50 overlay, edge map, colour difference and metrics. The overlay remains the main visual instrument.
Export profiles
uv run png2svg export work/name -o work/name/generated/final.svg
uv run png2svg export work/name -o work/name/generated/semantic.svg --profile semantic
uv run png2svg export work/name -o work/name/generated/animated.svg --profile animation
uv run png2svg export work/name -o work/name/generated/cropped.svg --tight --padding 2
compact is the default. It removes authoring IDs and unnecessary
whitespace, shortens paths and colours, and leaves out fixed width and height
attributes.
semantic keeps stable logical shape IDs. animation wraps every model
shape in a stable group so its fills and stroke move together. --tight
calculates the smallest safe viewBox without changing project.json.
Repository layout
skills/png2svg/ distributable skill and bundled engine
SKILL.md agent workflow
references/ conventions, model schema and worked reasoning
scripts/png2svg/ deterministic measurement and SVG library
scripts/*_template.py starting points for per-image reconstruction
examples/
assets/ the three publishable source images
build_keep_model.py fitted Keep construction
measure_n.py IN measurements
build_n_model.py IN model
measure_p.py P Auto measurements
build_p_model.py P Auto model
tests/ ground-truth and rendering regressions
work/ ignored private artwork, models and generated files
The Python package lives inside the skill so the installed skill remains
self-contained. pyproject.toml points at that single copy.
Develop the engine
uv sync
uv run pytest
uv run png2svg --help
uvx --from skills-ref agentskills validate ./skills/png2svg
The 87 tests cover deterministic generation, schema validation, security, subpixel measurement, reusable geometry, gradient fitting, export profiles and renderer regressions.
Artwork that works well
Clean logos with flat or gradient fills are the best fit. Lines, arcs, Béziers, overlapping primitives, conic sweeps and smoothed corners can all be reconstructed as editable geometry.
Textured renders can still produce useful SVGs. png2svg keeps their structure and large-scale shading while dropping grain, brushed metal and small photographic details. Low-frequency colour metrics are used for those cases.
Photographs, painterly artwork and tiny images under roughly 100px should use a contour tracer such as vtracer or potrace instead.
Current limitations
- SVG has no portable conic-gradient primitive. Conic fills compile to wedge fans, which cost more bytes than linear or radial gradients.
- Decomposition needs visual judgment, so there is no automatic
reconstructcommand. - The agent loop acts as the editor. There is no separate interactive UI.
License
The code is MIT licensed. Source images under examples/assets/ have
separate ownership and reuse terms described in their artwork notice.
No comments yet
Be the first to share your take.