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.2.tar.gz (40.9 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.2-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: svg_simplifier-1.0.2.tar.gz
  • Upload date:
  • Size: 40.9 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.2.tar.gz
Algorithm Hash digest
SHA256 e37af6e5deeb7d10f7330b0a4887beae333803c2068814c25fb59b6bfd211165
MD5 9dd14df4ee6acc7212dfccf30d9aa3cb
BLAKE2b-256 b89cfcb37df131352296187d692cafc88800518d8c5baa90688beb4dd0c5d6db

See more details on using hashes here.

File details

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

File metadata

  • Download URL: svg_simplifier-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 32.6 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 931414322f5b6bb468ecc92714ee1aaebe80ca4dcfe9720589d9a208415896fd
MD5 2c2699365539456cd2f222e694e83159
BLAKE2b-256 a78891b2abea04e408994d10984983d1bf605fd5f3666463c6a0c1a966143108

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