Metadata-Version: 2.4
Name: svgconverter
Version: 1.7.1
Summary: Embed or vectorize PNG, JPEG, WebP, BMP, and TIFF images as SVG.
Author: Chien-Hsun Chang
License-Expression: MIT
Project-URL: Homepage, https://github.com/KageRyo/SVGConverter
Project-URL: Documentation, https://github.com/KageRyo/SVGConverter#readme
Project-URL: Issues, https://github.com/KageRyo/SVGConverter/issues
Project-URL: Changelog, https://github.com/KageRyo/SVGConverter/blob/main/CHANGELOG.md
Keywords: image,svg,converter,raster,embed,vectorize
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Win32 (MS Windows)
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=10.0
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pyright>=1.1.390; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: twine>=6.0; extra == "dev"
Provides-Extra: vectorize
Requires-Dist: vtracer<1.0,>=0.6.15; extra == "vectorize"
Dynamic: license-file

# SVGConverter

[![CI](https://github.com/KageRyo/SVGConverter/actions/workflows/ci.yml/badge.svg)](https://github.com/KageRyo/SVGConverter/actions/workflows/ci.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=KageRyo_SVGConverter&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=KageRyo_SVGConverter)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=KageRyo_SVGConverter&metric=coverage)](https://sonarcloud.io/component_measures?id=KageRyo_SVGConverter&metric=coverage)
[![PyPI](https://img.shields.io/pypi/v/svgconverter.svg)](https://pypi.org/project/svgconverter/)
[![Python](https://img.shields.io/pypi/pyversions/svgconverter.svg)](https://pypi.org/project/svgconverter/)
[![License](https://img.shields.io/github/license/KageRyo/SVGConverter.svg)](LICENSE)

[正體中文](README_TW.md)

SVGConverter converts PNG, JPEG, WebP, BMP, and TIFF images to SVG through a
small Python API, command-line interface, and desktop GUI.

## At a glance

| Interface | Best for | Highlights |
| --- | --- | --- |
| Python API | Application integration and automation | Single files, mixed batches, metrics, progress, and cancellation |
| CLI | Scripts and repeatable workflows | Files, directories, recursion, output directories, and optimization |
| Desktop GUI | Interactive conversion | Both modes, conversion options, progress, and cancellation |

## Choose a conversion mode

```text
Raster image
    │
    ├── embed ─────> SVG <image> (pixels preserved by default)
    └── vectorize -> SVG <path>  (optional VTracer backend)
```

| Goal | Recommended mode | What to expect |
| --- | --- | --- |
| Preserve pixels, especially for photographs | `embed` | A self-contained SVG with an embedded raster; the default keeps the original raster bytes, while Base64 adds some overhead |
| Create editable paths from logos, icons, or line art | `vectorize` | VTracer-generated SVG paths; the result depends on tracing options and input complexity |
| Need both faithful and path-based output | Run both modes | They produce different representations; `embed` is not a substitute for vectorization |

### Representative inputs

| Input | `embed` | `vectorize` | Suggested choice |
| --- | --- | --- | --- |
| Photograph | Faithful pixels; size follows the source raster plus SVG/Base64 overhead | May become larger and stylized | `embed` |
| Logo or icon | Faithful raster appearance | Often a good path candidate; size depends on tracing settings | `vectorize` when editable paths are needed |
| High-contrast line art | Exact raster appearance | Usually a good path candidate | Choose based on fidelity versus editability |

## Conversion modes

- **`embed`** (default) places the original raster bytes in an SVG `<image>`
  element. It preserves the source pixels, but it is not vectorization and can
  be larger than the original image because of Base64 encoding.
- **`vectorize`** traces raster regions into SVG paths using the optional
  [VTracer](https://github.com/visioncortex/vtracer) backend. It is most useful
  for logos, icons, illustrations, and high-contrast line art. Photographs can
  produce large, stylized output rather than a faithful smaller image.

## Installation

SVGConverter requires Python 3.10 or newer:

```bash
python -m pip install --upgrade svgconverter
```

Install vectorization support when needed:

```bash
python -m pip install --upgrade "svgconverter[vectorize]"
```

To run the current development version instead:

```bash
git clone https://github.com/KageRyo/SVGConverter.git
cd SVGConverter
python -m pip install .
```

## Command line

Convert one image, retaining its dimensions in the generated SVG:

```bash
svgconverter image.png
svgconverter photo.jpg --output output.svg
svgconverter logo.png --mode vectorize --vectorize-color-mode binary
```

Convert all supported images immediately inside a directory:

```bash
svgconverter ./images --output-dir ./svg-output
```

Include nested directories while retaining their relative paths under the
output directory:

```bash
svgconverter ./images --output-dir ./svg-output --recursive
```

Convert several explicit files in one batch. Shells that support glob expansion
can also expand patterns such as `./images/*.png` before invoking the command:

```bash
svgconverter image.png photo.jpg --output-dir ./svg-output
```

For batch conversion, existing output SVGs are skipped unless `--overwrite` is
supplied; the final summary reports converted, skipped, and failed items.
Supported inputs are PNG, JPG, JPEG, WebP, BMP, TIF, and TIFF (including
upper-case extensions). Run `svgconverter --help` for all options. Vectorize
mode requires the optional `vectorize` extra.

When a wrapper passes paths from an untrusted user or agent, add
`--allowed-root ./workspace` to restrict resolved input and output paths to that
directory. Existing symlinks that resolve outside the boundary are rejected.
Without this option, the local CLI keeps its normal ability to access
user-selected filesystem locations.

### Embed optimization

Embed mode preserves the source raster bytes by default. Opt in to resizing or
re-encoding only when a smaller raster payload is worth the quality trade-off:

```bash
svgconverter photo.jpg --max-width 1600 --jpeg-quality 82
svgconverter illustration.png --png-compress-level 9 --optimize-png
```

`--max-width` and `--max-height` only downscale and preserve aspect ratio.
`--jpeg-quality` applies only to JPEG inputs; `--png-compress-level` and
`--optimize-png` apply only to PNG inputs, so the same batch options are safe
for mixed formats. A resized JPEG without an explicit quality uses 95. The CLI
reports input, embedded-raster, and SVG sizes after each conversion or batch.
These controls apply to `embed` mode only.

## Python API

```python
from svgconverter import (
    ConversionProgress,
    EmbedOptions,
    SVGConverter,
    convert_file,
    convert_file_with_metrics,
    convert_paths,
)

convert_file("image.png", "image.svg")
convert_file("logo.png", "logo.svg", mode="vectorize")
convert_file("workspace/image.png", allowed_root="workspace")

converter = SVGConverter(overwrite=True)
result = converter.convert_directory("./images", "./svg-output", recursive=True)
metric = convert_file_with_metrics(
    "photo.jpg",
    "photo.svg",
    embed_options=EmbedOptions(max_width=1600, jpeg_quality=82),
)


def report(progress: ConversionProgress) -> None:
    print(progress.completed, progress.total, progress.input_path)


batch = convert_paths(
    ["logo.png", "photo.jpg"], "./svg-output", progress_callback=report
)
print(result.success_count, result.skipped_count, result.failure_count)
print(metric.input_bytes, metric.embedded_raster_bytes, metric.svg_bytes)
```

`convert_file()` returns the output `pathlib.Path`. Directory conversion returns
a `BatchResult` containing successful output paths and per-file failures, so a
bad image does not abort the entire batch. `convert_paths()` accepts a mix of
files and directories; existing batch outputs are recorded as skips unless
`overwrite=True` is selected. `EmbedOptions` is opt-in; without it, embed mode
uses the original raster bytes. `convert_file_with_metrics()` and
`BatchResult.metrics` report source, embedded-raster, and SVG byte sizes.
Use `progress_callback` for each processed item; return `True` from
`should_cancel` to stop cleanly before the next item. The result then has
`cancelled=True`.

For integrations that accept untrusted path values, pass `allowed_root` to
`convert_file()`, `convert_file_with_metrics()`, `convert_directory()`,
`convert_paths()`, or `SVGConverter`. The converter resolves paths and rejects
inputs, outputs, and symlink escapes outside that directory. The default
`allowed_root=None` preserves the local library behavior.

## GUI

Install the package and run:

```bash
svgconverter-gui
```

The legacy development command `python main.py` starts the same GUI. Select one
or more files, or a folder, to convert with visible non-blocking progress and a
converted/skipped/failed summary. You can cancel between files; any per-file
errors are shown after the batch without closing the application. The GUI offers
Traditional Chinese, English, and Japanese, plus the following conversion
settings:

- Select `embed` or `vectorize` mode.
- Choose an output directory, overwrite existing SVG files, and optionally
  include nested folders.
- Configure embed resizing, JPEG quality, PNG compression, and PNG optimization.
- Configure common vectorize options such as color mode, hierarchy, curve mode,
  speckle filtering, color precision, layer difference, and path precision.

Vectorize mode requires the optional `vectorize` extra, just like the CLI and
Python API.

For a supported release, Windows users can download the standalone
`SVGConverter-vX.Y.Z-windows-x86_64.exe` asset from the GitHub Release page; it
does not require a local Python installation.

## Contributing and license

See [CONTRIBUTING.md](CONTRIBUTING.md) for local checks and commit conventions.
This project is licensed under the [MIT License](LICENSE).
