Python Glaxnimate
=================
Python bindings for [Glaxnimate](https://glaxnimate.mattbas.org/).
Allows to create and modify vector animations. With support for Lottie, SVG, and other formats.
See the [documentation page](https://glaxnimate.mattbas.org/contributing/scripting/) for more details.
## Examples
### Convert animated SVG to Lottie
```py
import glaxnimate
# Set up environment
with glaxnimate.environment.Headless():
# Create a document object
document = glaxnimate.model.Document("")
# Load an animated SVG
with open("MyFile.svg", "rb") as input_file:
glaxnimate.io.registry.from_extension("svg").load(document, input_file.read())
# ...
# Write to Lottie
with open("MyFile.json", "wb") as output_file:
output_file.write(glaxnimate.io.registry.from_extension("json").save(document))
```
### Render Lottie to gif
```py
from PIL import Image
from PIL import features
import glaxnimate
def png_gif_prepare(image):
"""
Converts the frame image from RGB to indexed, preserving transparency
"""
if image.mode not in ["RGBA", "RGBa"]:
image = image.convert("RGBA")
alpha = image.getchannel("A")
image = image.convert("RGB").convert('P', palette=Image.ADAPTIVE, colors=255)
mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
image.paste(255, mask=mask)
return image
def save_gif(document, file, skip_frames=1):
start = int(document.main.animation.first_frame)
end = int(document.main.animation.last_frame)
# Get all frames as PIL images
frames = []
for i in range(start, end+1, skip_frames):
frames.append(png_gif_prepare(document.render_image(i)))
# Save as animation
duration = int(round(1000 / document.main.fps * skip_frames / 10)) * 10
frames[0].save(
file,
format='GIF',
append_images=frames[1:],
save_all=True,
duration=duration,
loop=0,
transparency=255,
disposal=2,
)
# Initialize environment
with glaxnimate.environment.Headless():
document = glaxnimate.model.Document("")
# Load the lottie JSON
with open("MyFile.json", "rb") as input_file:
glaxnimate.io.registry.from_extension("json").load(document, input_file.read())
# Save as GIF
with open("MyFile.gif", "rb") as output_file:
save_gif(document, output_file)
```
### Create animations from code
```py
import glaxnimate
with glaxnimate.environment.Headless():
# Create an empty document
document = glaxnimate.model.Document("")
# Add a layer
layer = document.main.add_shape("Layer")
# The fill will be applied to all following shapes in the same group / layer
fill = layer.add_shape("Fill")
fill.color.value = "#ff0000"
# A simple circle moving left and right
ellipse = layer.add_shape("Ellipse")
radius = 64
ellipse.position.set_keyframe(0, glaxnimate.utils.Point(radius, document.size.height / 2))
ellipse.position.set_keyframe(90, glaxnimate.utils.Point(document.size.width-radius, document.size.height / 2))
ellipse.position.set_keyframe(180, glaxnimate.utils.Point(radius, document.size.height / 2))
ellipse.size.value = glaxnimate.utils.Size(radius, radius)
# Export it
with open("MyFile.svg", "wb") as output_file:
output_file.write(glaxnimate.io.registry.from_extension("svg").save(document))
```
## Dependencies
This module depends on the following system libraries
* Qt5 (widgets, xml)
* potrace
* libav / ffmpeg
* libarchive
To install them on Ubuntu and similar:
```bash
apt install libqt5widgets5 libqt5xml5 potrace ffmpeg libarchive13
```
Raw data
{
"_id": null,
"home_page": "https://glaxnimate.mattbas.org/",
"name": "glaxnimate",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3",
"maintainer_email": "",
"keywords": "telegram stickers tgs lottie svg animation",
"author": "Mattia Basaglia",
"author_email": "mattia.basaglia@gmail.com",
"download_url": "",
"platform": null,
"description": "Python Glaxnimate\n=================\n\nPython bindings for [Glaxnimate](https://glaxnimate.mattbas.org/).\n\nAllows to create and modify vector animations. With support for Lottie, SVG, and other formats.\n\nSee the [documentation page](https://glaxnimate.mattbas.org/contributing/scripting/) for more details.\n\n## Examples\n\n### Convert animated SVG to Lottie\n\n```py\nimport glaxnimate\n\n# Set up environment\nwith glaxnimate.environment.Headless():\n # Create a document object\n document = glaxnimate.model.Document(\"\")\n\n # Load an animated SVG\n with open(\"MyFile.svg\", \"rb\") as input_file:\n glaxnimate.io.registry.from_extension(\"svg\").load(document, input_file.read())\n\n # ...\n\n # Write to Lottie\n with open(\"MyFile.json\", \"wb\") as output_file:\n output_file.write(glaxnimate.io.registry.from_extension(\"json\").save(document))\n```\n\n\n### Render Lottie to gif\n\n\n```py\nfrom PIL import Image\nfrom PIL import features\nimport glaxnimate\n\n\ndef png_gif_prepare(image):\n \"\"\"\n Converts the frame image from RGB to indexed, preserving transparency\n \"\"\"\n if image.mode not in [\"RGBA\", \"RGBa\"]:\n image = image.convert(\"RGBA\")\n alpha = image.getchannel(\"A\")\n image = image.convert(\"RGB\").convert('P', palette=Image.ADAPTIVE, colors=255)\n mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)\n image.paste(255, mask=mask)\n return image\n\n\ndef save_gif(document, file, skip_frames=1):\n start = int(document.main.animation.first_frame)\n end = int(document.main.animation.last_frame)\n\n # Get all frames as PIL images\n frames = []\n for i in range(start, end+1, skip_frames):\n frames.append(png_gif_prepare(document.render_image(i)))\n\n # Save as animation\n duration = int(round(1000 / document.main.fps * skip_frames / 10)) * 10\n frames[0].save(\n file,\n format='GIF',\n append_images=frames[1:],\n save_all=True,\n duration=duration,\n loop=0,\n transparency=255,\n disposal=2,\n )\n\n# Initialize environment\nwith glaxnimate.environment.Headless():\n\n document = glaxnimate.model.Document(\"\")\n\n # Load the lottie JSON\n with open(\"MyFile.json\", \"rb\") as input_file:\n glaxnimate.io.registry.from_extension(\"json\").load(document, input_file.read())\n\n # Save as GIF\n with open(\"MyFile.gif\", \"rb\") as output_file:\n save_gif(document, output_file)\n```\n\n### Create animations from code\n\n```py\nimport glaxnimate\n\nwith glaxnimate.environment.Headless():\n # Create an empty document\n document = glaxnimate.model.Document(\"\")\n\n # Add a layer\n layer = document.main.add_shape(\"Layer\")\n\n # The fill will be applied to all following shapes in the same group / layer\n fill = layer.add_shape(\"Fill\")\n fill.color.value = \"#ff0000\"\n\n # A simple circle moving left and right\n ellipse = layer.add_shape(\"Ellipse\")\n radius = 64\n ellipse.position.set_keyframe(0, glaxnimate.utils.Point(radius, document.size.height / 2))\n ellipse.position.set_keyframe(90, glaxnimate.utils.Point(document.size.width-radius, document.size.height / 2))\n ellipse.position.set_keyframe(180, glaxnimate.utils.Point(radius, document.size.height / 2))\n ellipse.size.value = glaxnimate.utils.Size(radius, radius)\n\n # Export it\n with open(\"MyFile.svg\", \"wb\") as output_file:\n output_file.write(glaxnimate.io.registry.from_extension(\"svg\").save(document))\n```\n\n## Dependencies\n\nThis module depends on the following system libraries\n\n* Qt5 (widgets, xml)\n* potrace\n* libav / ffmpeg\n* libarchive\n\nTo install them on Ubuntu and similar:\n\n```bash\napt install libqt5widgets5 libqt5xml5 potrace ffmpeg libarchive13\n```\n\n\n",
"bugtrack_url": null,
"license": "GNU General Public License v3 or later (GPLv3+)",
"summary": "Python bindings for Glaxnimate",
"version": "0.5.4",
"project_urls": {
"Chat": "https://t.me/Glaxnimate",
"Code": "https://gitlab.com/mattbas/glaxnimate",
"Documentation": "https://glaxnimate.mattbas.org/",
"Downloads": "https://glaxnimate.mattbas.org/download/",
"Homepage": "https://glaxnimate.mattbas.org/",
"Issues": "https://gitlab.com/mattbas/glaxnimate/-/issues"
},
"split_keywords": [
"telegram",
"stickers",
"tgs",
"lottie",
"svg",
"animation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fdda2e70d44ae2ac44c4b91fd387dc8fc272ab1f74ab073393b14cd9d27264e6",
"md5": "51bf79bb39d2ee0a521cc6a174c88d8b",
"sha256": "4c6ca855d92906de5a8a29619022855727e77be9eb0d1e7fdb43eb6869d63a26"
},
"downloads": -1,
"filename": "glaxnimate-0.5.4-py3-none-manylinux1_x86_64.whl",
"has_sig": false,
"md5_digest": "51bf79bb39d2ee0a521cc6a174c88d8b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3",
"size": 49193336,
"upload_time": "2023-09-09T14:07:50",
"upload_time_iso_8601": "2023-09-09T14:07:50.029490Z",
"url": "https://files.pythonhosted.org/packages/fd/da/2e70d44ae2ac44c4b91fd387dc8fc272ab1f74ab073393b14cd9d27264e6/glaxnimate-0.5.4-py3-none-manylinux1_x86_64.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-09 14:07:50",
"github": false,
"gitlab": true,
"bitbucket": false,
"codeberg": false,
"gitlab_user": "mattbas",
"gitlab_project": "glaxnimate",
"lcname": "glaxnimate"
}