All posts

From Photo to Vector with vtracer

·2 min read

I wanted the Kathmandu skyline in the hero banner of my site as an SVG — not an icon, not a stock illustration, but something derived from an actual photograph. SVG scales cleanly at any resolution, compresses well, and can be styled with CSS. A PNG of the same width would be five times heavier. So I needed to trace a photo into vectors.

Why Not Inkscape or Illustrator

The obvious options were Adobe Illustrator's Image Trace and Inkscape's built-in tracer, which wraps potrace. I tried Inkscape first. For simple high-contrast line art, potrace is fine. For a skyline photo with gradients and noise, it spits out thousands of jagged micro-paths that look reasonable at a glance but break apart on zoom and produce bloated output. Illustrator does better but costs a subscription I don't have.

vtracer

vtracer is a Rust CLI tool by VisionCortex, available at visioncortex/vtracer on GitHub. The algorithm builds a hierarchical stack of shapes rather than tracing edges pixel by pixel, which is why the curve output is smoother on photographic material. There's also a browser-based version if you want to experiment without installing anything.

Install it with Cargo:

cargo install vtracer

The basic invocation is straightforward:

vtracer --input kathmandu.jpg --output kathmandu-skyline.svg

That gets you something usable immediately.

The Two Flags That Mattered

The defaults are reasonable, but two options made a significant difference on my image.

--filter_speckle controls the minimum pixel area of a region before vtracer bothers tracing it. The default is 4. On a photo with sky noise and small distant buildings, I pushed this to 16. It removed a large number of meaningless micro-shapes without losing any of the major silhouette detail.

--colormode was the other key choice. The default color mode traces every distinct color region and can produce large, detailed SVGs. For a skyline where I wanted a flat graphic, binary worked better — it reduces the image to two tones before tracing. The result was a clean dark shape on transparent, which is exactly right for layering in CSS.

vtracer --input kathmandu.jpg --output kathmandu-skyline.svg \
  --colormode binary \
  --filter_speckle 16

What I Got

A 47 KB SVG with clean Bézier paths, no jagged edges, and a silhouette that looked intentional rather than machine-traced. It scaled cleanly from mobile to 4K. CSS fill targeting worked immediately. The equivalent PNG at 1200px wide came in around 230 KB.

There's a limit to what tracing can do. The source photo matters — high contrast, good lighting, a subject that isn't too busy. For photographic material with real-world noise, vtracer holds up better than potrace-based tools. But you're still working within the limits of what the source gives you.


If you need a quick raster-to-vector conversion and don't want to open a GUI, vtracer is the right tool to reach for.

Share this post