Skip to main content

Production-ready SVG path geometry simplification with Bézier curve fitting

Project description

SVG Simplifier Logo

License: MIT Python 3.12+ PyPI version Production Ready

SVG Simplifier

A production-ready Python library for simplifying SVG path geometry while preserving visual appearance. This tool implements advanced algorithms including adaptive curve flattening, Douglas-Peucker simplification, and Schneider's Bézier curve fitting to achieve 60-90% node reduction with minimal quality loss.

Features

  • High-Quality Simplification: 60% minimum, 90% preferred node reduction
  • Visual Preservation: Maximum 0.05% deviation from original (configurable)
  • Corner Preservation: Automatic sharp corner and cusp detection
  • Complete SVG Support: All path commands, primitives, and transformations
  • Production Ready: Type hints, comprehensive tests, multiprocessing support

Installation

pip install svg-simplifier

Or install from source:

git clone https://github.com/svg-simplifier/svg-simplifier.git
cd svg-simplifier
pip install -e ".[dev]"

Quick Start

Command Line

# Basic usage
svgsimplify input.svg output.svg

# With custom tolerance
svgsimplify logo.svg logo_simple.svg --tolerance 0.005 --stats

# High precision output
svgsimplify complex.svg simple.svg --tolerance 0.01 --precision 8

Python API

from simplifier import Simplifier

# Create simplifier with default options
simplifier = Simplifier()

# Simplify file
result = simplifier.simplify_file("input.svg", "output.svg")
print(f"Reduced by {result.reduction_percentage:.1%}")

# Simplify string
with open("input.svg") as f:
    svg_string = f.read()

output_svg, result = simplifier.simplify_string(svg_string)

Algorithm Pipeline

  1. Flatten Curves: Adaptive subdivision based on curvature
  2. Remove Duplicates: Eliminate coincident points
  3. Remove Collinear: Remove points on straight lines
  4. Douglas-Peucker: Polyline simplification with tolerance
  5. Curve Fitting: Schneider's algorithm for Bézier fitting
  6. Curve Merging: Combine adjacent curves where possible
  7. Optimization: Fine-tune control points
  8. Self-Intersection Check: Repair introduced artifacts

Supported SVG Features

Elements

  • <path> - Full path command support
  • <rect>, <circle>, <ellipse> - Converted to paths
  • <line>, <polyline>, <polygon> - Converted to paths
  • <g> - Group transformations
  • <defs>, <use> - Definitions and references
  • <symbol>, <clipPath>, <mask> - Handled appropriately

Path Commands

All SVG path commands supported (absolute and relative):

  • M/m - Moveto
  • L/l - Lineto
  • H/h, V/v - Horizontal/Vertical lineto
  • C/c, S/s - Cubic Bézier
  • Q/q, T/t - Quadratic Bézier
  • A/a - Arcs (converted to Bézier curves)
  • Z/z - Closepath

Transformations

  • translate, scale, rotate
  • skewX, skewY
  • matrix
  • Nested groups
  • viewBox handling

CLI Options

svgsimplify INPUT OUTPUT [OPTIONS]

Options:
  --tolerance FLOAT       Simplification tolerance (default: 0.001)
  --max-error FLOAT       Maximum fitting error (default: 0.0005)
  --corner-angle FLOAT    Corner detection angle in degrees (default: 30)
  --remove-duplicates     Remove duplicate points (default: True)
  --merge-curves          Merge adjacent curves (default: True)
  --precision INT         Output precision (default: 6)
  --verbose               Verbose output
  --stats                 Print statistics
  --help                  Show help message

Examples

Example 1: Simple Logo

svgsimplify examples/simple_logo.svg output.svg --tolerance 0.002 --stats

Output:

Simplification Statistics
========================================
Original nodes:     44
Optimized nodes:    16
Reduction:          63.6%
Execution time:     0.023s

Example 2: Complex Illustration

svgsimplify examples/complex_illustration.svg output.svg --tolerance 0.01

This example demonstrates significant reduction on complex artwork with many geometric shapes.

Performance

Benchmark results on AMD Ryzen 7 5800X:

Paths Original Nodes Time Target Met
10 440 0.05s
100 4,400 0.45s
500 22,000 2.1s
1000 44,000 4.2s

Target: 1000 paths under 5 seconds ✓

Development

Running Tests

# Run all tests
pytest

# With coverage
pytest --cov=simplifier --cov-report=html

# Specific test file
pytest tests/test_geometry.py

# Benchmark tests
pytest tests/ -m benchmark

Code Quality

# Format code
black simplifier/ tests/ benchmarks/

# Lint
ruff check simplifier/ tests/

# Type check
mypy simplifier/

Project Structure

svg_simplifier/
├── simplifier/           # Main package
│   ├── __init__.py
│   ├── cli.py           # Command-line interface
│   ├── parser.py        # SVG parsing
│   ├── optimizer.py     # Simplification engine
│   ├── bezier.py        # Bézier operations
│   ├── geometry.py      # Geometric utilities
│   ├── transforms.py    # Transformation handling
│   ├── svg_writer.py    # SVG output
│   └── utils.py         # Utilities
├── tests/               # Test suite
├── benchmarks/          # Performance benchmarks
├── examples/            # Example SVG files
├── requirements.txt     # Dependencies
├── pyproject.toml      # Project configuration
└── README.md           # This file

Algorithm Details

Adaptive Flattening

Curves are adaptively flattened based on curvature analysis. High-curvature regions receive more sample points while smooth regions use fewer.

Douglas-Peucker Simplification

The classic polyline simplification algorithm reduces points while maintaining shape fidelity within the specified tolerance.

Schneider's Curve Fitting

Implementation of "An Algorithm for Automatically Fitting Digitized Curves" (Graphics Gems) by Philip J. Schneider:

  1. Compute chord-length parameterization
  2. Estimate tangent directions
  3. Solve for optimal control points using least squares
  4. Subdivide if error exceeds tolerance

Curve Merging

Adjacent curves are merged when the combined approximation error remains within tolerance, further reducing node count.

Limitations

  • Text elements are not converted to paths
  • Gradients and patterns are preserved but not optimized
  • Filters and effects are preserved but not analyzed
  • Very small files may see limited benefit
  • Complex self-intersecting paths may require manual review

Contributing

See CONTRIBUTING.md for the full developer guide.

Quick checklist:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make changes with tests — coverage must not drop
  4. Run the full quality pipeline (black, ruff, mypy, pytest)
  5. Commit changes (git commit -m 'Add amazing feature')
  6. Push to branch (git push origin feature/amazing-feature)
  7. Open a Pull Request targeting main

Developer Rules

Full details in CONTRIBUTING.md.

Rule Detail
Python version 3.12+ only
Style black (line-length 100) + ruff
Types Strict mypy — all public functions must be fully typed
Tests pytest — no PR merged with failing tests or reduced coverage
Package layout Core logic lives in simplifier/; never add modules outside this package without discussion
Dependencies Add runtime deps to pyproject.toml [dependencies], dev deps to [dev]
No secrets Never commit API keys, credentials, or personal data
Commits Conventional Commits style (feat:, fix:, docs:, refactor:, test:, chore:)

License

This project is released under the MIT License — one of the most permissive open-source licenses available.

MIT License

Copyright (c) 2024 SVG Simplifier Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

See the LICENSE file for the full text.

References

Acknowledgments

  • Graphics Gems for the curve fitting algorithm
  • svgpathtools for path utilities
  • lxml for XML parsing

Made with ❤️ for the vector graphics community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

svg_simplifier-1.0.1.tar.gz (40.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

svg_simplifier-1.0.1-py3-none-any.whl (32.5 kB view details)

Uploaded Python 3

File details

Details for the file svg_simplifier-1.0.1.tar.gz.

File metadata

  • Download URL: svg_simplifier-1.0.1.tar.gz
  • Upload date:
  • Size: 40.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for svg_simplifier-1.0.1.tar.gz
Algorithm Hash digest
SHA256 4a1b0d5f9305a1003b95b572836c43e73536e64800cfcd5648cfb8473b11b8bd
MD5 5c119d2dc88ce7602d53782eebe09599
BLAKE2b-256 89d06b732c75e584f8376ebd73e3b9b6e870d6fc8e310cd5af6794372271e63f

See more details on using hashes here.

File details

Details for the file svg_simplifier-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: svg_simplifier-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 32.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for svg_simplifier-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a2dd6645b29d4d6d6b2b60dd8aa1b21ab5820375ddaea8189153b25e0cf22d0e
MD5 0a576d12bc99304cc2c63a592499c266
BLAKE2b-256 eed32b4972220829f613b9ccb7025790f9399f68ce21e51e00ca3471fd47f2b5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page