{"id":25483690,"url":"https://github.com/romelium/framesvg","last_synced_at":"2025-12-28T07:05:33.576Z","repository":{"id":277896129,"uuid":"928533030","full_name":"Romelium/FrameSVG","owner":"Romelium","description":"A web app, command-line tool, and Python library to convert animated GIFs into animated SVGs. framesvg offers automatic playback, scalability, and customizable VTracer options for optimal vectorization.","archived":false,"fork":false,"pushed_at":"2025-04-13T13:13:18.000Z","size":6626,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-28T18:18:28.150Z","etag":null,"topics":["animated-svg","cli","command-line","command-line-tool","converter","gif","gif-animation","gifs","image-converter","python","python-library","raster-to-vector","svg","svg-animations","vtracer","web","web-graphics","webapp","website"],"latest_commit_sha":null,"homepage":"https://framesvg.romelium.cc","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Romelium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-06T19:32:41.000Z","updated_at":"2025-05-12T16:23:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d21b6b4-718b-42d6-91ee-9603adc916d4","html_url":"https://github.com/Romelium/FrameSVG","commit_stats":null,"previous_names":["romelium/framesvg"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Romelium/FrameSVG","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romelium%2FFrameSVG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romelium%2FFrameSVG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romelium%2FFrameSVG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romelium%2FFrameSVG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Romelium","download_url":"https://codeload.github.com/Romelium/FrameSVG/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romelium%2FFrameSVG/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266626115,"owners_count":23958344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animated-svg","cli","command-line","command-line-tool","converter","gif","gif-animation","gifs","image-converter","python","python-library","raster-to-vector","svg","svg-animations","vtracer","web","web-graphics","webapp","website"],"created_at":"2025-02-18T17:39:37.042Z","updated_at":"2025-12-28T07:05:33.566Z","avatar_url":"https://github.com/Romelium.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg height=\"250\" src=\"images/framesvg.svg\" alt=\"FrameSVG Logo\" /\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eConvert animated GIFs to animated SVGs.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://framesvg.romelium.cc\"\u003e\u003cstrong\u003e🌐 Try the Web App\u003c/strong\u003e\u003c/a\u003e\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n  \u003ca href=\"https://github.com/romelium/framesvg/actions/workflows/tests.yml\"\u003e\u003cimg alt=\"Build Status\" src=\"https://img.shields.io/github/actions/workflow/status/romelium/framesvg/tests.yml?style=flat-square\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/framesvg/\"\u003e\u003cimg alt=\"PyPI Version\" src=\"https://img.shields.io/pypi/v/framesvg?style=flat-square\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/framesvg/\"\u003e\u003cimg alt=\"Python Versions\" src=\"https://img.shields.io/pypi/pyversions/framesvg?style=flat-square\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003c!-- Kyubey Animation Block --\u003e\n\u003cimg align=\"left\" hspace=\"10\" src=\"images/kyubey.svg\" alt=\"Kyubey SVG Image\"/\u003e\n\u003cimg align=\"right\" hspace=\"10\" src=\"images/kyubey.svg\" alt=\"Kyubey SVG Image\"/\u003e\n\n`framesvg` is a [web app](https://framesvg.romelium.cc), command-line tool, and Python library that converts animated GIFs into animated SVGs. It leverages the power of [VTracer](https://www.visioncortex.org/vtracer/) for raster-to-vector conversion, producing smooth, scalable, and *true vector* animations.\n\nThis 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.\n\n\u003cbr clear=\"both\"/\u003e\n\n## 📑 Table of Contents\n\n- [Features](#-features)\n- [Examples](#-examples)\n  - [Coding Examples](#coding-examples)\n  - [General Examples](#general-examples)\n  - [Transparent/Binary Examples](#transparentbinary-examples)\n- [Installation](#-installation)\n- [Usage](#-usage)\n  - [Command Line Interface](#command-line-interface)\n  - [Python Library](#python-library)\n- [Configuration \u0026 Options](#-configuration--options)\n- [API Reference](#-api-reference)\n- [Optimization Guide](#-optimization-guide)\n- [Development](#-development)\n\n## ✨ Features\n\n*   **True Vector Output:** Creates scalable vector graphics, not embedded rasters.\n*   **Automatic Playback:** Generated SVGs play automatically in browsers and image viewers.\n*   **Network Efficiency:** SVGs are text-based. When served with Gzip or Brotli compression, they can load significantly faster than GIFs.\n*   **Flexible Tooling:** Available as a [Web App](https://framesvg.romelium.cc), CLI tool, and Python library.\n*   **Highly Configurable:** Fine-tune the vectorization process (speckle filtering, smoothing, color precision) to balance quality vs. file size.\n*   **Variable Frame Rate Support:** Preserves the specific duration of each frame from the original GIF.\n\n## 🎨 Examples\n\n\u003e **Note:** You can view a live comparison gallery on the [Examples Page](https://framesvg.romelium.cc/examples.html).\n\n### Coding Examples\n\n| Original GIF | Converted SVG |\n| :---: | :---: |\n| \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock Git.gif\" height=\"200\" alt=\"Git GIF\"\u003e | \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock Git.svg\" height=\"200\" alt=\"Git SVG\"\u003e |\n| \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock GitHub.gif\" height=\"200\" alt=\"GitHub GIF\"\u003e | \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock GitHub.svg\" height=\"200\" alt=\"GitHub SVG\"\u003e |\n| \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock VSCode.gif\" height=\"200\" alt=\"VSCode GIF\"\u003e | \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock VSCode.svg\" height=\"200\" alt=\"VSCode SVG\"\u003e |\n| \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock Sublime.gif\" height=\"200\" alt=\"Sublime GIF\"\u003e | \u003cimg src=\"images/Code Coding GIF by EscuelaDevRock Sublime.svg\" height=\"200\" alt=\"Sublime SVG\"\u003e |\n\n### General Examples\n\n| Original GIF | Converted SVG |\n| :---: | :---: |\n| \u003cimg src=\"images/Good_Morning_GIF_by_Hello_All.gif\" height=\"200\" alt=\"Good Morning GIF\"\u003e | \u003cimg src=\"images/Good_Morning_GIF_by_Hello_All.svg\" height=\"200\" alt=\"Good Morning SVG\"\u003e |\n| \u003cimg src=\"images/icon_loading_GIF.gif\" height=\"200\" alt=\"Loading GIF\"\u003e | \u003cimg src=\"images/icon_loading_GIF.svg\" height=\"200\" alt=\"Loading SVG\"\u003e |\n| \u003cimg src=\"images/voila hands GIF by brontron.gif\" height=\"200\" alt=\"Voila GIF\"\u003e | \u003cimg src=\"images/voila hands GIF by brontron.svg\" height=\"200\" alt=\"Voila SVG\"\u003e |\n\n### Transparent/Binary Examples\n\nThese 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).\n\n| Original GIF | Converted SVG |\n| :---: | :---: |\n| \u003cimg src=\"images/black and white loop GIF by Sculpture.gif\" height=\"200\" alt=\"Loop GIF\"\u003e | \u003cimg src=\"images/black and white loop GIF by Sculpture.svg\" height=\"200\" alt=\"Loop SVG\"\u003e |\n| \u003cimg src=\"images/Black And White Loop GIF by Pi-Slices.gif\" height=\"200\" alt=\"Pi-Slices GIF\"\u003e | \u003cimg src=\"images/Black And White Loop GIF by Pi-Slices.svg\" height=\"200\" alt=\"Pi-Slices SVG\"\u003e |\n\n## 📦 Installation\n\n### Option 1: Using pip (Recommended for Library use)\n\n```bash\npip install framesvg\n```\n\n### Option 2: Using [pipx](https://pipx.pypa.io/latest/installation/) (Recommended for CLI use)\n\nIf you only need the command-line tool, `pipx` installs it in an isolated environment.\n\n```bash\npipx install framesvg\n```\n\n## 🚀 Usage\n\n### Command-Line Interface\n\nBasic conversion:\n```bash\nframesvg input.gif\n```\n\nSpecify output filename and force 24 FPS:\n```bash\nframesvg input.gif output.svg --fps 24\n```\n\nOptimize for file size (High filtering, low precision):\n```bash\nframesvg input.gif --filter-speckle 10 --color-precision 4 --mode polygon\n```\n\n### Python Library\n\n```python\nfrom framesvg import gif_to_animated_svg_write, gif_to_animated_svg\n\n# 1. Convert and save directly to a file\ngif_to_animated_svg_write(\"input.gif\", \"output.svg\", fps=30)\n\n# 2. Get SVG content as a string (useful for web apps)\nsvg_content = gif_to_animated_svg(\"input.gif\")\nprint(f\"Generated SVG size: {len(svg_content)} bytes\")\n\n# 3. Advanced: Custom VTracer options\noptions = {\n    \"mode\": \"spline\",       # Smoother curves\n    \"filter_speckle\": 2,    # Keep more detail\n    \"colormode\": \"binary\"   # Black and white\n}\ngif_to_animated_svg_write(\"input.gif\", \"artistic.svg\", vtracer_options=options)\n```\n\n## ⚙️ Configuration \u0026 Options\n\nThese options control the VTracer engine. Tweak these to balance **Visual Fidelity** vs. **File Size**.\n\n| Flag | Option | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `-f` | `--fps` | *None* | Animation speed. Defaults to GIF frame delays; falls back to 10. |\n| `-c` | `--colormode` | `color` | `color` (standard) or `binary` (threshold-based transparency). |\n| `-m` | `--mode` | `polygon` | `polygon` (smaller files), `spline` (smoother curves), or `none`. |\n| `-s` | `--filter-speckle` | `4` | **Crucial.** Cleans up noise. Higher = smaller file, less detail. |\n| `-p` | `--color-precision` | `8` | Bit-depth of colors. Lower = fewer colors, smaller file. |\n| `-d` | `--layer-difference` | `16` | Gradient threshold. Higher = fewer layers, smaller file. |\n| `-i` | `--hierarchical` | `stacked` | `stacked` (shapes on top of others) or `cutout`. |\n| | `--corner-threshold` | `60` | Minimum angle to be considered a corner. |\n| | `--length-threshold` | `4.0` | Minimum path length to render. |\n| | `--splice-threshold` | `45` | Angle threshold for splitting splines. |\n\n## 📚 API Reference\n\n### `gif_to_animated_svg`\n\n```python\ndef gif_to_animated_svg(\n    gif_path: str,\n    vtracer_options: dict | None = None,\n    fps: float | None = None\n) -\u003e str\n```\n\nReads a GIF file and returns the animated SVG content as a string.\n\n*   **`gif_path`**: Path to the source GIF.\n*   **`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`).\n*   **`fps`**: Force a specific frame rate. If `None`, uses the GIF's original frame delays.\n\n### `gif_to_animated_svg_write`\n\n```python\ndef gif_to_animated_svg_write(\n    gif_path: str,\n    output_svg_path: str,\n    vtracer_options: dict | None = None,\n    fps: float | None = None\n) -\u003e None\n```\n\nReads a GIF file, converts it, and saves the result directly to `output_svg_path`.\n\n## 📉 Optimization Guide\n\nVectorizing complex raster images can result in large files. Here is how to keep file size under control:\n\n1.  **Increase Speckle Filter (`-s`):** This is the most effective setting. Try increasing it to `10` or higher to remove small \"dust\" artifacts.\n2.  **Use Polygon Mode (`-m polygon`):** Splines look smoother but require more data. Polygons are often sufficient for animation and significantly smaller.\n3.  **Reduce Color Precision (`-p`):** Dropping this to `6` or `4` reduces the palette size, merging similar colors.\n4.  **Simplify the Source:** If possible, reduce the noise or dither in the source GIF before converting.\n\n\u003e **Tip:** Use the [VTracer Online Demo](https://www.visioncortex.org/vtracer/) to visualize how these parameters affect a single frame before converting the whole animation.\n\n## 🛠 Development\n\n### Setup\n\nWe use [Hatch](https://hatch.pypa.io/latest/install) for dependency management.\n\n```bash\n# Install Hatch\npip install hatch\n\n# Run tests\nhatch test\n\n# Format and Lint\nhatch fmt\n```\n\n### Web App Development\n\nThe web interface is built with vanilla HTML/JS and Python serverless functions (Vercel).\n\n1.  **Install Vercel CLI:** `npm install -g vercel`\n2.  **Run Locally:**\n    ```bash\n    vercel dev\n    ```\n    *Note: Set the root directory to `./web` when prompted.*\n\n## 🤝 Contributing\n\nContributions are welcome! Please submit pull requests or open issues on the [GitHub repository](https://github.com/romelium/framesvg).\n\n## 📄 License\n\nMIT License © 2025 Romelium\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromelium%2Fframesvg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromelium%2Fframesvg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromelium%2Fframesvg/lists"}