How Potrace Vectorizes Monochrome Images to SVG
Vectorization tools like Potrace transform raster bitmaps into Scalable Vector Graphics (SVG) through a deterministic mathematical pipeline. This process converts discrete, resolution-dependent pixels into smooth, continuous geometric paths by systematically executing thresholding, boundary contour extraction, polygon simplification, smooth Bézier curve fitting, and vector markup generation.
1. Binarization and Preprocessing
The pipeline begins by converting the input image into a pure monochrome grid where each pixel is either foreground (black) or background (white). If the input is color or grayscale, a thresholding algorithm—such as global luminance thresholding or Otsu’s method—is applied to establish a clean binary bitmap. This step ensures that clear boundaries exist without intermediate anti-aliasing artifacts interfering with the edge detection logic.
2. Contour Tracing
Once the bitmap is binarized, the algorithm traces the outlines of connected pixel groups. It traverses the perimeter between black and white pixels using a boundary-following technique similar to the Moore-Neighbor tracing or Marching Squares algorithm. During this stage, the tool resolves directional ambiguities (such as checkerboard pixel intersections) using consistent turn policies (e.g., always turning left or prioritizing black connectivity). The result is an ordered series of closed, pixel-aligned loops representing the outer boundaries of shapes and inner cutouts (holes).
3. Polygon Approximation
The raw pixel paths produce jagged, staircase-like contours. To simplify these, the algorithm constructs an initial polygon that approximates the pixel path within a user-defined error tolerance. Potrace uses a variation of shortest-path algorithms and convex hull approximations to find the polygon with the minimal number of vertices that still encloses the original boundary without exceeding the allowable pixel deviation. Collinear segments and redundant vertices are merged or eliminated.
4. Smooth Curve Fitting
Straight-line polygonal segments are subsequently converted into smooth curves. The algorithm evaluates sequences of polygon vertices to determine whether they represent sharp corners or smooth transitions:
- Corner Detection: Vertices with sharp angles exceeding a designated threshold are preserved as explicit corners (lines joining at a point).
- Bézier Approximation: Sequences of vertices designated as smooth curves are fitted using cubic Bézier segments. The engine calculates optimal control points using least-squares approximation, minimizing the squared distance between the mathematical curve and the original contour points.
- Continuity Enforcement: Tangent vectors at the join points between adjacent Bézier segments are aligned to maintain smooth visual continuity (\(C^1\) or \(G^1\) continuity).
5. Path Optimization and Curve Adjustment
The engine executes an optimization pass balancing fidelity against path complexity. It applies penalty functions to weigh curve accuracy against the total number of segments. If replacing two adjacent Bézier curves with a single segment falls within the acceptable error threshold, the algorithm combines them to minimize the final file size and computational overhead.
6. SVG Output Generation
Finally, the optimized mathematical descriptions are translated into
vector markup. Each closed contour is mapped to an SVG
<path> element using standard path commands: *
M (moveto) for the initial coordinate. * L
(lineto) for straight polygon edges. * C (curveto) for
cubic Bézier curves with their respective control points. *
Z (closepath) to seal the loop.
Inner cutouts and outer shapes are combined using the SVG
fill-rule="evenodd" or fill-rule="nonzero"
attribute, producing a scalable, resolution-independent vector rendering
of the original monochrome bitmap.