Covecto architecture: why two vectorization engines
When we started building Covecto, the question was not whether we could vectorize images. Plenty of tools do that. The question was why every existing tool seemed to excel at one type of image while producing garbage on another. Icon converters make photos look like stained glass. Photo tracers turn crisp pixel art into wobbly approximations. The root cause is that vectorization is not one problem. It is two distinct problems that happen to share an input format.
Covecto ships with two independent vectorization engines: PixelExact and Spline. This post covers why we built both, how each one works, and how the auto heuristic picks between them.
The vectorization problem
Raster images store color at discrete pixel positions. Vector formats store geometry as paths and fills. Converting raster to vector means deciding which pixels belong together, what shape best represents that group, and how to express that shape as compact path data.
The hard part is that "best representation" depends entirely on what the image is. A 24x24 app icon has sharp edges, flat colors, and exact pixel boundaries. A 4000x3000 photograph has gradients, noise, and organic curves. If you trace both with the same algorithm, one of them will look wrong.
Most vectorization tools pick a side. They either preserve pixel boundaries exactly (good for icons, terrible for photos) or fit smooth curves through color regions (good for photos, terrible for icons). Covecto refuses to choose.
PixelExact engine
PixelExact is built for images where every pixel matters: icons, pixel art, flat logos, and simple lineart with hard edges.
The pipeline works in three stages. First, it identifies contiguous color regions using flood-fill. Two adjacent pixels belong to the same region only if they share the same color. No tolerance, no blending. Second, it traces the boundary of each region by walking the pixel perimeter. Third, it emits rectilinear SVG paths that snap to exact pixel coordinates.
The result is vector output that reproduces the source image with zero ambiguity. A 2-pixel-wide stroke in the original stays exactly 2 pixels wide in the vector. Corners are sharp. Colors are flat. There is no curve fitting and no approximation.
Where PixelExact struggles is photographic content. A photo has thousands of distinct colors due to compression noise and natural gradients. Flood-fill produces thousands of tiny regions. The boundary tracer generates enormous path lists. The output SVG is technically correct but impractically large and visually noisy.
Spline engine
Spline is built for images with continuous tone and organic shapes: photographs, illustrations with gradients, and complex artwork.
Spline uses vtracer 0.6.5 under the hood. The pipeline starts with color quantization, reducing the image to a manageable palette. Then it traces contours around each quantized color band. Finally, it fits Bezier splines along those contours, producing smooth curves that approximate the original shape boundaries.
The output is compact and smooth. A sky gradient becomes a handful of curved bands rather than thousands of pixel rectangles. A portrait retains recognizable facial structure through curved color regions.
The trade-off is precision. Spline does not preserve pixel boundaries. A straight horizontal line in the source might become a Bezier curve with a slight bow. For icons and pixel art, this is unacceptable. The smoothness that helps photos actively harms flat artwork.
Auto heuristic
Covecto's auto mode selects an engine by analyzing image characteristics before vectorizing. The heuristic looks at several signals:
- Color count: Few distinct colors points to PixelExact. Hundreds or thousands points to Spline.
- Edge sharpness: Hard transitions between adjacent pixels favor PixelExact. Gradual transitions favor Spline.
- Image dimensions: Small images (under 128x128) tend to be icons. Large images tend to be photos or illustrations.
- Region count after flood-fill: If flood-fill produces a small number of large regions, PixelExact will produce clean output. If it produces a large number of tiny regions, Spline is the better choice.
The heuristic is not perfect. It can be overridden explicitly by passing --engine pixelexact or --engine spline on the CLI, or by selecting a profile.
Covecto ships four built-in profiles that preconfigure engine and parameters:
- icon: PixelExact, tuned for small flat graphics
- logo: PixelExact with slightly more relaxed color matching
- photo: Spline with aggressive color quantization
- lineart: Spline with minimal color reduction, optimized for stroke-based artwork
Trade-offs in practice
Here is a practical guide for choosing an engine:
Use PixelExact when the source has flat colors, hard edges, and exact pixel boundaries. Icons, pixel art, simple logos, and UI mockups all qualify. The output will be larger than Spline for complex images but will preserve every detail.
Use Spline when the source has gradients, noise, or organic curves. Photos, digital paintings, and scanned illustrations benefit from curve fitting and color reduction. The output will be smaller and smoother but will not preserve exact pixel positions.
Use auto when you are processing mixed batches and cannot inspect each image individually. The heuristic gets it right most of the time. For production pipelines where you know the image type, pin the engine explicitly.
Architecture notes
The workspace is organized as three Rust crates:
- covecto-core: Both engines, the auto heuristic, profiles, and SVG optimization
- covecto-cli: Command-line interface with Rayon-based parallel batch processing
- covecto-api: REST API built on axum 0.8
All three output formats (SVG, PDF, EPS) are generated from the same internal path representation. SVG optimization runs both as a standalone tool and as a post-vectorize step to strip redundant path data.
Batch processing uses Rayon for parallelism. Each image in a batch is independent, so the parallelism strategy is straightforward: map each input file to a vectorization task and let Rayon distribute them across threads.
Future improvements
The auto heuristic is conservative. It errs toward PixelExact for anything ambiguous, which is usually safer but not always optimal. We plan to add more signal types, including frequency-domain analysis to detect photographic content more reliably.
Spline currently depends on vtracer 0.6.5. Future versions may integrate newer tracing algorithms or offer alternative curve fitting strategies.
PixelExact output can grow large for images with many regions. A region-merging pass that combines adjacent same-color regions before path emission could reduce output size significantly without sacrificing precision.
Covecto is MIT licensed and available now at v0.1.1. The first commit landed on July 22, 2026. v0.1.0 shipped the next day, and v0.1.1 followed on July 24 with profile fixes and API improvements. If you are vectorizing images in a Rust pipeline, give it a try and file issues for anything that looks wrong.