img2svg 0.1.4

A rust native image to SVG converter in CLI/MCP/Library
Documentation

img2svg

A high-performance image to SVG converter written in Rust. Transform raster images (PNG, JPEG, etc.) into scalable vector graphics with cubic Bézier curves, edge-aware quantization, and advanced path optimization.

Tests License

Why img2svg?

The Problem

Converting raster images to vector format is essential for:

  • Scalability: Vector graphics scale infinitely without quality loss
  • File size optimization: Simple shapes often result in smaller SVG files than raster counterparts
  • Editability: Vectors can be modified in design tools (Illustrator, Inkscape, Figma)
  • Web performance: SVGs are code-based and can be optimized, animated, and styled with CSS

Why img2svg?

Feature img2svg ImageMagick Potrace Vector Magic
Pure Rust ❌ (C++) ❌ (C) ❌ (Web only)
Color Support ✅ Full color ❌ B&W only
Library API ❌ CLI only ❌ CLI only ❌ Web only
MCP Server
Local Processing ❌ (Cloud)
Open Source
Advanced Algorithms ⚠️ Basic ⚠️ Basic

Key Advantages

  1. Cubic Bézier Curves: Smooth curves via least-squares fitting with Newton-Raphson reparameterization
  2. Edge-Aware Quantization: K-means++ with perceptual color distance and Sobel edge detection
  3. Sub-pixel Accuracy: Marching squares contour extraction with corner-aware path splitting
  4. Smart SVG Output: L for lines, C for curves, collinear merge, thin stripe fast path
  5. Auto Photo Preprocessing: Bilateral filter + color reduction for photographs
  6. Flexible Usage: CLI tool, Rust library, and MCP server

Examples & Quality

See the examples/ directory for sample conversions demonstrating quality.

Simple Graphics (8 colors)

Input Output
simple.png simple.svg

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/simple.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/simple.svg -c 8 -s 3
  • Input: 50x50 PNG (2KB) - Basic geometric shapes
  • Output: SVG with clean vector paths
  • Result: Perfect edges, scalable without quality loss

Gradients (16 colors)

Input Output
gradient.png gradient.svg

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/gradient.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/gradient.svg -c 16 -s 5
  • Input: 100x100 PNG (1KB) - Smooth gradient
  • Output: SVG with banding minimized
  • Result: Smooth color transitions, vector-friendly

Medium Complexity (16 colors)

Input Output
medium.png medium.svg

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/medium.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/medium.svg -c 16 -s 5
  • Input: 100x100 PNG (2KB)
  • Output: SVG with clean regions
  • Result: Preserves shapes, smooth curves

Complex Illustration (16 colors)

Input Output
complex.png complex.svg

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/complex.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/complex.svg -c 16 -s 5
  • Input: 200x200 PNG (6KB) - Detailed illustration
  • Output: SVG with fine details preserved
  • Result: Clean paths, scalable

Very Complex (32 colors)

Input Output
very_complex.png very_complex.svg

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/very_complex.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/very_complex.svg -c 32 -s 7
  • Input: 200x200 PNG (13KB) - Highly detailed
  • Output: SVG with complex paths
  • Result: Details preserved, clean vector output

Photograph with Preprocessing (Lenna)

Photographs benefit from the --preprocess flag which applies edge-preserving smoothing and color reduction.

Input PNG Output SVG (with --preprocess)
lenna.png lenna.svg

Comparison:

  • Without preprocessing: 87 KB SVG with heavy color banding
  • With preprocessing: 28 KB SVG (67% smaller) with cleaner regions

Details:

  • Command: img2svg -i https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/input/lenna.png -o https://raw.githubusercontent.com/yingkitw/img2svg/main/examples/output/lenna.svg --preprocess -c 12 -t 0.15 -s 3
  • Input: 512x512 PNG - Standard test photograph
  • Output: Vector version with preprocessing applied
  • Result: Preprocessing significantly reduces file size and color banding for photographs

What preprocessing does:

  • Bilateral filtering: Smooths flat areas while preserving edges
  • Color reduction: Reduces color noise before quantization
  • Result: Cleaner color regions, smaller file size, less posterization

Comparison with Alternatives

# ImageMagick trace (often produces jagged edges)
convert input.png svg:output-imagemagick.svg

# img2svg (smooth curves, better color accuracy)
img2svg -i input.png -o img2svg.svg -c 16 -s 5

Quality Differences:

  • img2svg: Smooth curves, accurate colors, compact paths
  • ImageMagick: Often produces jagged edges, limited color optimization
  • Potrace: B&W only, requires pre-processing for color images

Installation

CLI Tool

# From crates.io
cargo install img2svg

# From source
git clone https://github.com/yingkitw/img2svg.git
cd img2svg
cargo install --path .

Library

Add to your Cargo.toml:

[dependencies]
img2svg = "0.1"

MCP Server

cd mcp-server
cargo install --path .

Usage

CLI Tool

# Basic conversion
img2svg -i input.png -o output.svg

# Photo with preprocessing (recommended for photographs)
img2svg -i photo.jpg -o photo.svg --preprocess -c 12

# High-quality graphics with more colors
img2svg -i logo.png -o logo.svg -c 32 -s 7

# Simple logo with fewer colors
img2svg -i icon.png -o icon.svg -c 8 -s 2

# Batch convert multiple files
for img in *.png; do
    img2svg -i "$img" -o "${img%.png}.svg"
done

Options

Option Short Default Description
--input -i required Input image file (PNG, JPEG, etc.)
--output -o auto Output SVG file (defaults to input with .svg extension)
--preprocess -p false Apply edge-preserving smoothing and color reduction (great for photos)
--colors -c 16 Number of colors for quantization (1-64)
--threshold -t 0.1 Edge detection threshold (0.0-1.0)
--smooth -s 5 Path smoothing level (0-10)
--original false Use original pipeline (line segments, RDP) instead of default Bézier
--hierarchical false Enable hierarchical decomposition (original pipeline only)
--advanced -a false Use advanced SVG generation (original pipeline only)

Rust Library

use img2svg::{convert, ConversionOptions};
use std::path::Path;

// Simple conversion with defaults
let options = ConversionOptions::default();
convert(
    Path::new("input.png"),
    Path::new("output.svg"),
    &options
)?;

// Custom options for better quality
let options = ConversionOptions {
    num_colors: 32,
    smooth_level: 7,
    threshold: 0.05,
    ..Default::default()
};
convert(Path::new("photo.jpg"), Path::new("photo.svg"), &options)?;

// Low-detail conversion for simple graphics
let options = ConversionOptions {
    num_colors: 8,
    smooth_level: 2,
    ..Default::default()
};

MCP Server

The MCP (Model Context Protocol) server is built into the same codebase and allows AI assistants (like Claude Desktop) to convert images to SVG directly.

Installation

The MCP server binary is built automatically with the main project:

# Build both CLI and MCP server
cargo build --release

# Or install both binaries
cargo install --path .

The binaries will be:

  • img2svg - CLI tool
  • img2svg-mcp - MCP server

Configuration for Claude Desktop

Add to your Claude Desktop MCP configuration file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "img2svg": {
      "command": "/path/to/img2svg-mcp",
      "args": []
    }
  }
}

Replace /path/to/img2svg-mcp with the full path to the installed binary:

  • If installed via cargo install: Run which img2svg-mcp to find the path
  • If built locally: Usually at target/release/img2svg-mcp

Usage

Once configured, restart Claude Desktop and use the tool directly in conversations:

"Convert the image at /path/to/logo.png to SVG with 8 colors"

The MCP server provides one tool:

  • convert_image_to_svg: Converts raster images to SVG format
    • input_path (required): Path to input image
    • output_path (required): Path for output SVG
    • num_colors (optional): Number of colors (1-64, default: 16)
    • smooth_level (optional): Smoothing level (0-10, default: 5)
    • threshold (optional): Edge detection threshold (0.0-1.0, default: 0.1)

Algorithm

img2svg uses a sophisticated multi-stage pipeline (default Bézier pipeline):

  1. Edge Detection: Sobel gradient for edge-aware quantization boundaries
  2. Color Quantization: K-means++ initialization + k-means refinement with perceptual color distance
  3. Majority-Vote Smoothing: Edge-aware smoothing merges thin artifacts (adaptive: 4 passes for graphics, 2 for photos)
  4. Contour Tracing: Marching squares on per-color binary masks produces sub-pixel-accurate boundaries
  5. Thin Stripe Fast Path: Contours < 2px → direct SVG rectangles (preserves line patterns)
  6. Corner-Preserving Smoothing: Gaussian smoothing that preserves sharp corners
  7. Visvalingam-Whyatt Simplification: Area-based point removal with corner preservation
  8. Edge Snapping + Corner Injection: Points snapped to image edges; 90° corners injected at edge transitions
  9. Cubic Bézier Fitting: Least-squares fit with Newton-Raphson reparameterization + G1 continuity
  10. SVG Generation: L for lines, C for curves, collinear merge, gap-filling strokes

The original pipeline (--original) uses median-cut quantization, RDP simplification, and line-segment SVG paths.

Performance

img2svg is optimized for speed and memory:

  • Speed: Typical 1000x1000 image converts in <1 second
  • Memory: Efficient streaming processing, suitable for large images
  • Parallelization: Color quantization can be parallelized for large palettes

Benchmarks (1000x1000px image):

Colors Time Output Size
8 0.3s 45 KB
16 0.5s 78 KB
32 0.8s 156 KB
64 1.4s 312 KB

Tips for Best Results

For Logos and Icons

  • Use fewer colors (8-16)
  • Lower smoothing (2-4)
  • Higher threshold (0.15-0.2)
  • Results: Clean vector shapes, small file size

For Photos

Best results: Use --preprocess flag which applies edge-preserving smoothing and color reduction

# Recommended for photos
img2svg -i photo.jpg -o photo.svg --preprocess -c 12 -t 0.15 -s 3

What preprocessing does:

  • Bilateral filtering: Smooths flat areas while preserving edges
  • Color reduction: Reduces color noise before quantization
  • Result: Cleaner regions, smaller file size, less posterization

Without preprocessing:

  • Use fewer colors (8-12)
  • Higher threshold (0.15-0.2)
  • Lower smoothing (2-4)

For Illustrations

  • Medium colors (16-32)
  • Medium smoothing (4-6)
  • Default threshold (0.1)

For Clip Art

  • Fewer colors (4-8)
  • Higher smoothing (3-5)
  • Higher threshold (0.15-0.25)

Limitations

  • Best with: Images with clear color boundaries (logos, icons, flat illustrations)
  • Photos: Use --preprocess flag for better results, but expect some loss of detail
  • Not suitable for: Highly detailed photorealistic images with complex gradients
  • For complex photos, consider keeping the original raster format

Contributing

Contributions are welcome! Please see TODO.md for planned improvements.

License

Apache License 2.0 - see LICENSE for details.

Acknowledgments

  • Median-cut algorithm: Paul Heckbert (1980)
  • Marching squares: William E. Lorensen (1987)
  • RDP algorithm: Ramer & Douglas & Peucker (1972-1973)