Convert animated GIFs to animated SVGs.
framesvg is a web app, command-line tool, and Python library that converts animated GIFs into animated SVGs. It leverages the power of VTracer for raster-to-vector conversion, producing smooth, scalable, and true vector animations.
This is a significant improvement over embedding raster images (like GIFs) directly within SVGs, as framesvg generates genuine vector output that plays automatically and scales beautifully. Ideal for readmes, documentation, and web graphics.
📑 Table of Contents
- Features
- Examples
- Installation
- Usage
- Configuration & Options
- API Reference
- Optimization Guide
- Development
✨ Features
- True Vector Output: Creates scalable vector graphics, not embedded rasters.
- Automatic Playback: Generated SVGs play automatically in browsers and image viewers.
- Network Efficiency: SVGs are text-based. When served with Gzip or Brotli compression, they can load significantly faster than GIFs.
- Flexible Tooling: Available as a Web App, CLI tool, and Python library.
- Highly Configurable: Fine-tune the vectorization process (speckle filtering, smoothing, color precision) to balance quality vs. file size.
- Variable Frame Rate Support: Preserves the specific duration of each frame from the original GIF.
🎨 Examples
Note: You can view a live comparison gallery on the Examples Page.
Coding Examples
| Original GIF | Converted SVG |
|---|---|
General Examples
| Original GIF | Converted SVG |
|---|---|
Transparent/Binary Examples
These examples use the binary color mode. All bright colors turn transparent. (If they appear dark here, it is due to the transparency on a dark background; they look correct on light backgrounds).
| Original GIF | Converted SVG |
|---|---|
📦 Installation
Option 1: Using pip (Recommended for Library use)
pip install framesvg
Option 2: Using pipx (Recommended for CLI use)
If you only need the command-line tool, pipx installs it in an isolated environment.
pipx install framesvg
🚀 Usage
Command-Line Interface
Basic conversion:
framesvg input.gif
Specify output filename and force 24 FPS:
framesvg input.gif output.svg --fps 24
Optimize for file size (High filtering, low precision):
framesvg input.gif --filter-speckle 10 --color-precision 4 --mode polygon
Python Library
from framesvg import gif_to_animated_svg_write, gif_to_animated_svg
# 1. Convert and save directly to a file
gif_to_animated_svg_write("input.gif", "output.svg", fps=30)
# 2. Get SVG content as a string (useful for web apps)
svg_content = gif_to_animated_svg("input.gif")
print(f"Generated SVG size: {len(svg_content)} bytes")
# 3. Advanced: Custom VTracer options
options = {
"mode": "spline", # Smoother curves
"filter_speckle": 2, # Keep more detail
"colormode": "binary" # Black and white
}
gif_to_animated_svg_write("input.gif", "artistic.svg", vtracer_options=options)
⚙️ Configuration & Options
These options control the VTracer engine. Tweak these to balance Visual Fidelity vs. File Size.
| Flag | Option | Default | Description |
|---|---|---|---|
-f |
--fps |
None | Animation speed. Defaults to GIF frame delays; falls back to 10. |
-c |
--colormode |
color |
color (standard) or binary (threshold-based transparency). |
-m |
--mode |
polygon |
polygon (smaller files), spline (smoother curves), or none. |
-s |
--filter-speckle |
4 |
Crucial. Cleans up noise. Higher = smaller file, less detail. |
-p |
--color-precision |
8 |
Bit-depth of colors. Lower = fewer colors, smaller file. |
-d |
--layer-difference |
16 |
Gradient threshold. Higher = fewer layers, smaller file. |
-i |
--hierarchical |
stacked |
stacked (shapes on top of others) or cutout. |
--corner-threshold |
60 |
Minimum angle to be considered a corner. | |
--length-threshold |
4.0 |
Minimum path length to render. | |
--splice-threshold |
45 |
Angle threshold for splitting splines. |
📚 API Reference
gif_to_animated_svg
def gif_to_animated_svg(
gif_path: str,
vtracer_options: dict | None = None,
fps: float | None = None
) -> str
Reads a GIF file and returns the animated SVG content as a string.
gif_path: Path to the source GIF.vtracer_options: A dictionary of VTracer parameters. Keys correspond to the CLI flags above, but use underscores instead of hyphens (e.g.,filter_speckle,color_precision).fps: Force a specific frame rate. IfNone, uses the GIF's original frame delays.
gif_to_animated_svg_write
def gif_to_animated_svg_write(
gif_path: str,
output_svg_path: str,
vtracer_options: dict | None = None,
fps: float | None = None
) -> None
Reads a GIF file, converts it, and saves the result directly to output_svg_path.
📉 Optimization Guide
Vectorizing complex raster images can result in large files. Here is how to keep file size under control:
- Increase Speckle Filter (
-s): This is the most effective setting. Try increasing it to10or higher to remove small "dust" artifacts. - Use Polygon Mode (
-m polygon): Splines look smoother but require more data. Polygons are often sufficient for animation and significantly smaller. - Reduce Color Precision (
-p): Dropping this to6or4reduces the palette size, merging similar colors. - Simplify the Source: If possible, reduce the noise or dither in the source GIF before converting.
Tip: Use the VTracer Online Demo to visualize how these parameters affect a single frame before converting the whole animation.
🛠 Development
Setup
We use Hatch for dependency management.
# Install Hatch
pip install hatch
# Run tests
hatch test
# Format and Lint
hatch fmt
Web App Development
The web interface is built with vanilla HTML/JS and Python serverless functions (Vercel).
- Install Vercel CLI:
npm install -g vercel - Run Locally:
vercel devNote: Set the root directory to./webwhen prompted.
🤝 Contributing
Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.
📄 License
MIT License © 2025 Romelium
Metadata
Release files for framesvg 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| framesvg-0.3.0.tar.gz | 10.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| framesvg-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.9 kB
Release files / framesvg-0.3.0.tar.gz
| Download URL | framesvg-0.3.0.tar.gz |
|---|---|
| Size | 10.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3df6b32fe70ce8a7e316b3670db6c9c193084a599967628f68525e106447d02b
|
|
BLAKE2b-256 checksum How to use checksums |
dca91a03051b926c4cfbcf42956ae3a625234216b6bbfe441bed7fe16932fd2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.16.2 cpython/3.12.3 HTTPX/0.28.1
|
Release files / framesvg-0.3.0-py3-none-any.whl
| Download URL | framesvg-0.3.0-py3-none-any.whl |
|---|---|
| Size | 10.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92502a646983f9364125de4239bb469a788a634909b7b8af1f392d9a4b640ab0
|
|
BLAKE2b-256 checksum How to use checksums |
76cc89b5bd70a48e55272d6cfb531a0d8475c5e0ba628bf75aff89601e00c8ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.16.2 cpython/3.12.3 HTTPX/0.28.1
|