Python Lottie

April 29, 2021 ยท View on GitHub

A Python framework to work with Lottie files and Telegram animated stickers.

(Repo forked from https://gitlab.com/mattbas/python-lottie.git)

Quick start

This section describes some common things you might want to do without having to read the whole README

Installation

pip install lottie

Converting into images

This package provide the script lottie_convert.py, it's precise location depends on how you installed python-lottie.

For PNG, GIF, and Webp you have to install cairosvg and pillow.

To render a still image:

lottie_convert.py input_file.json output_file.png --frame 30

To render an animated image (GIF or WebP):

lottie_convert.py input_file.json output_file.webp

A list of supported formats is described in the section "Supported Formats" below.

Turning GIF and such into animations

The lottie format is for vector graphics, this means converting raster images usually doesn't work too well.

That said, python-lottie does support a few different algorithms to import raster images, the process is a bit slow for larger images but use it with caution.

To use the potrace vectorization library, install the extras tagged as "trace".

Once set up, just invoke lottie_convert.py using the vectorization algorithm

lottie_convert.py input_file.gif output_file.json --bmp-mode trace

For pixel art, you can use the pizel algorithm, which doesn't require potrace

lottie_convert.py input_file.gif output_file.json --bmp-mode pixel

If you are ok with keeping raster images as such, you can use the default mode

lottie_convert.py input_file.gif output_file.json

Converting Telegram animated stickers (tgs)

This format is natively supported by python lottie, but telegram doesn't support all of the features supported by lottie (see the section labeled "Supported After Effects Features" for details).

When converting from tgs, nothing special is needed as it's handled as a lottie animation.

lottie_convert.py AnimatedSticker.tgs output_file.webp

But when converting into animated stickers, you might end up with a file that Telegram doesn't recognize. To help with this, by default lottie_convert.py will scale the animation to be the right size and framerate. It will also print out any warnings related to unsupported features. Everything else works like any other conversion:

lottie_convert.py input_file.json output_file.tgs

If you want to see the same warnings for an existing tgs file use tgs_check.py

tgs_check.py AnimatedSticker.tgs

Creating animations from scratch

See the examples at https://mattbas.gitlab.io/python-lottie/examples.html and read the available lottie objects at https://mattbas.gitlab.io/python-lottie/group__Lottie.html#details

Features

Here is a list of features of the lottie python framework:

  • Loading compressed TGS and uncompressed lottie JSON
  • Manipulation of lottie objects
  • Simple animation presets (eg: shake, linear bounce)
  • Bezier path animations (eg: follow path, making paths appear and disappear)
  • Wave distortion animation (eg: for flags)
  • Pseudo-3D rotations
  • Animation easing functions
  • Inverse Kinematic solver
  • Pretty printing and comparison of lottie files
  • Rendering text as shapes

Supported Formats

FormatImportImport AnimatedExportExport Animated
lottie๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
tgs๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
SVG๐Ÿ‘๐Ÿ‘๐Ÿ‘โ›”๏ธ
SVGz๐Ÿ‘๐Ÿ‘๐Ÿ‘โ›”๏ธ
PNG๐Ÿ‘๐Ÿ‘1๐Ÿ‘โ›”๏ธ
Synfig๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
WebP๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
dotLottie๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
PostScriptโ›”๏ธโ›”๏ธ๐Ÿ‘โ›”๏ธ
PDFโ›”๏ธโ›”๏ธ๐Ÿ‘โ›”๏ธ
BMP๐Ÿ‘๐Ÿ‘1โ›”๏ธโ›”๏ธ
GIF๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
TIFF๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
MP4โ›”๏ธโ›”๏ธ๐Ÿ‘๐Ÿ‘
AVIโ›”๏ธโ›”๏ธ๐Ÿ‘๐Ÿ‘
WebMโ›”๏ธโ›”๏ธ๐Ÿ‘๐Ÿ‘
HTMLโ›”๏ธโ›”๏ธ๐Ÿ‘๐Ÿ‘
Blender๐Ÿ‘2๐Ÿ‘2โ›”๏ธโ›”๏ธ
Krita๐Ÿ‘โ›”๏ธโ›”๏ธโ›”๏ธ

Scripts

python-lottie provides several scripts to convert or manage lottie animations. For full documentation see https://mattbas.gitlab.io/python-lottie/scripts.html

The main one is lottie_convert.py, which can be used to convert between the supported formats.

There is also the script lottie_gui.py which provides a graphical interface for lottie playback.

Installation

Downloads

The packages for the various applications listed below can be downloaded from here:

Synfig

There's a Synfig studio plugin to export telegram stickers. To install, just copy (or symlink) ./addons/synfig/pylot-exporter into the synfig plugin directory. You might have to copy ./lib/lottie in there as well.

Inkscape

There are some import/export extensions for inkscape.

Just copy (or symlink) the files under ./addons/inkscape to the inkscape extension directory. On my system that's ~/.config/inkscape/extensions/ but you can double check from Inkscape: Edit > Preferences... > System > User extensions

Note that the extensions require Python 3. If they are run with a python 2 interpreter, they will try to run themselves using python3.

They also need the lottie framework to be in the python path, otherwise you can manually set the path on the import/export dialogues.

See also https://inkscape.org/~mattia.basaglia/%E2%98%85tgslottie-importexport

Blender

There are some export addons for blender.

Copy (or symlink) the files under ./addons/blender to the Blender extension directory.

On my system that's ~/.config/blender/2.80/scripts/addons/ you can check available paths through the Blender Python console:

import addon_utils; print(addon_utils.paths())

You can also install the addon from Blender using the zipfile created by make.

Pip

You can install from pypi:

pip install lottie

from git:

pip install git+https://gitlab.com/mattbas/python-lottie.git@master

for the source directory:

pip install /path/to/the/sources # this is the path where setup.py is located

Requirements

Python 3.

Optional Requirements

In order to provide lean installations, this framework doesn't have dependencies for its core functionality.

To add support for extra formats or advanced functionality, you can install additional packages.

These requirements are declared as extra in the Pypi package, follows a table listing dependencies and features

PackagesExtraFeature
pillowimagesTo load image assets
cairosvgPNGTo export PNG / PDF / PS
cairosvg, pillowGIFTo export GIF and animated WebP
fonttoolstextTo render text as shapes
graphemeemojiAdding emoji support to text rendering
cairosvg, numpy, Python OpenCV 2videoTo export video
pillow, pypotrace>=0.2, numpy, scipytraceTo convert raster images into vectors
QScintillaGUIGrafical user interface utilities
coverageTo show unit test coverage, used optionally by test.sh

If intalling from pip, you can install optional requirements like so:

pip install lottie[GIF]

The above example will ensure cairosvg and pillow are installed. For more details see https://pip.pypa.io/en/latest/reference/pip_install/#examples.

For convenience, an additional extra requirements is defined, so you can install all dependencies at once:

pip install lottie[all]

If you are using python-lottie from source you can run

pip install -r requirements.txt

Which will install all the requirements (except for pypotrace, as that package has some issues)

Telegram Animated Stickers

I had to reverse engineer the format because Telegram couldn't be bothered providing the specs.

A TGS file is a gzip compressed JSON, the JSON data is described here: https://mattbas.gitlab.io/python-lottie/group__Lottie.html#lottie_json

Making your own exporters converters

Lottie format

If you can get the source image into lottie format, that's 90% of the work done.

I've created Python classes based the format schema and after effects documentation, which output the correct json. Eg:

foo = lottie.Animation()
# ...
json.dump(foo.to_dict(), output_file)

I'm also creating a proper documentation for the format, see: https://mattbas.gitlab.io/tgs/group__Lottie.html#details

TGS changes

Nothing major, just ensure the root JSON object has tgs: 1

Gzipping

The tgs file is the JSON described above compressed into a gzip, and renamed to .tgs

License

AGPLv3+ https://www.gnu.org/licenses/agpl-3.0.en.html

Credits

Copyright 2019 (C) Mattia Basaglia

Documentation

https://mattbas.gitlab.io/python-lottie/index.html

Code

https://gitlab.com/mattbas/python-lottie/

Chat

https://t.me/tgs_stuff

Download

https://mattbas.gitlab.io/python-lottie/downloads.html

Here you can download packages for pip, blender, and inkscape before they are released. These packages always have the latest features but they might be unstable.

Issues

You can report any issue in the tracker on gitlab:

https://gitlab.com/mattbas/python-lottie/-/issues

Supported After Effects Features

Compare with http://airbnb.io/lottie/#/supported-features

Legend

  • ๐Ÿ‘ Supported
  • โ” Unknown / untested
  • โ›”๏ธ Not supported
  • python-lottie refers to this framework in general
  • Telegram refers to features supported by telegram animated stickers
  • SVG refers to the exported SVG images from this framework, features supported here will also reflect on other formats (such as video, png, and similar)

Telegram doesn't support everything in the Lottie format. https://core.telegram.org/animated_stickers lists some things that are unsupported but what is listed there isn't correct.

There are several things marked as unsupported in telegram animated stickers that are actually supported.

Shapespython-lottieTelegramSVG
Shape๐Ÿ‘๐Ÿ‘๐Ÿ‘
Ellipse๐Ÿ‘๐Ÿ‘๐Ÿ‘
Rectangle๐Ÿ‘๐Ÿ‘๐Ÿ‘
Rounded Rectangle๐Ÿ‘๐Ÿ‘๐Ÿ‘
Polystar๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Group๐Ÿ‘๐Ÿ‘๐Ÿ‘
Trim Path (individually)๐Ÿ‘๐Ÿ‘๐Ÿ‘
Trim Path (simultaneously)๐Ÿ‘๐Ÿ‘๐Ÿ‘
Fillspython-lottieTelegramSVG
Color๐Ÿ‘๐Ÿ‘๐Ÿ‘
Opacity๐Ÿ‘๐Ÿ‘๐Ÿ‘
Radial Gradient๐Ÿ‘๐Ÿ‘๐Ÿ‘
Linear Gradient๐Ÿ‘๐Ÿ‘๐Ÿ‘
Fill Rule๐Ÿ‘๐Ÿ‘๐Ÿ‘
Strokespython-lottieTelegramSVG
Color๐Ÿ‘๐Ÿ‘๐Ÿ‘
Opacity๐Ÿ‘๐Ÿ‘๐Ÿ‘
Width๐Ÿ‘๐Ÿ‘๐Ÿ‘
Line Cap๐Ÿ‘๐Ÿ‘๐Ÿ‘
Line Join๐Ÿ‘๐Ÿ‘๐Ÿ‘
Miter Limit๐Ÿ‘๐Ÿ‘๐Ÿ‘
Dashes๐Ÿ‘๐Ÿ‘๐Ÿ‘
Gradient๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Transformspython-lottieTelegramSVG
Position๐Ÿ‘๐Ÿ‘๐Ÿ‘
Position (separated X/Y)๐Ÿ‘๐Ÿ‘๐Ÿ‘
Scale๐Ÿ‘๐Ÿ‘๐Ÿ‘
Rotation๐Ÿ‘๐Ÿ‘๐Ÿ‘
Anchor Point๐Ÿ‘๐Ÿ‘๐Ÿ‘
Opacity๐Ÿ‘๐Ÿ‘๐Ÿ‘
Parenting๐Ÿ‘๐Ÿ‘๐Ÿ‘
Skew๐Ÿ‘โ›”๏ธ4๐Ÿ‘
Auto Orient๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Interpolationpython-lottieTelegramSVG
Linear Interpolation๐Ÿ‘๐Ÿ‘๐Ÿ‘
Bezier Interpolation๐Ÿ‘๐Ÿ‘๐Ÿ‘
Hold Interpolation๐Ÿ‘๐Ÿ‘๐Ÿ‘
Spatial Bezier Interpolation๐Ÿ‘๐Ÿ‘๐Ÿ‘
Rove Across Timeโ›”๏ธโ›”๏ธ5โ›”๏ธ
Maskspython-lottieTelegramSVG
Mask Path๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Mask Opacity๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Add๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Subtract๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Intersect๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Lighten๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Darken๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Difference๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Expansion๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Feather๐Ÿ‘๐Ÿ‘3โ›”๏ธ
Mattespython-lottieTelegramSVG
Alpha Matte๐Ÿ‘โ›”๏ธ6๐Ÿ‘
Alpha Inverted Matte๐Ÿ‘โ›”๏ธ6โ›”๏ธ
Luma Matte๐Ÿ‘โ›”๏ธ6๐Ÿ‘
Luma Inverted Matte๐Ÿ‘โ›”๏ธ6โ›”๏ธ
Merge Pathspython-lottieTelegramSVG
Mergeโ›”๏ธโ›”๏ธ5โ›”๏ธ
Addโ›”๏ธโ›”๏ธ5โ›”๏ธ
Subtractโ›”๏ธโ›”๏ธ5โ›”๏ธ
Intersectโ›”๏ธโ›”๏ธ5โ›”๏ธ
Exclude Intersectionโ›”๏ธโ›”๏ธ5โ›”๏ธ
Layer Effectspython-lottieTelegramSVG
Fill๐Ÿ‘โ›”๏ธโ›”๏ธ
Stroke๐Ÿ‘โ›”๏ธโ›”๏ธ
Tint๐Ÿ‘โ›”๏ธโ›”๏ธ
Tritone๐Ÿ‘โ›”๏ธโ›”๏ธ
Levels Individual Controls๐Ÿ‘โ›”๏ธโ›”๏ธ
Text 7python-lottieTelegramSVG
Glyphs๐Ÿ‘โ›”๏ธโ›”๏ธ
Fonts๐Ÿ‘โ›”๏ธโ›”๏ธ
Transform๐Ÿ‘โ›”๏ธโ›”๏ธ
Fill๐Ÿ‘โ›”๏ธ๐Ÿ‘
Stroke๐Ÿ‘โ›”๏ธโ›”๏ธ
Trackingโ›”๏ธโ›”๏ธโ›”๏ธ
Anchor point groupingโ›”๏ธโ›”๏ธโ›”๏ธ
Text Pathโ›”๏ธโ›”๏ธโ›”๏ธ
Per-character 3Dโ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Units)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Based on)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Amount)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Shape)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Ease High)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Ease Low)โ›”๏ธโ›”๏ธโ›”๏ธ
Range selector (Randomize order)โ›”๏ธโ›”๏ธโ›”๏ธ
expression selectorโ›”๏ธโ›”๏ธโ›”๏ธ
Otherpython-lottieTelegramSVG
Expressionsโ›”๏ธโ›”๏ธ5โ›”๏ธ
Images๐Ÿ‘โ›”๏ธ๐Ÿ‘
Precomps๐Ÿ‘๐Ÿ‘๐Ÿ‘
Time Stretch๐Ÿ‘โ›”๏ธโ›”๏ธ
Time remap๐Ÿ‘โ›”๏ธ6๐Ÿ‘
Markersโ›”๏ธโ›”๏ธ5โ›”๏ธ
3D Layers๐Ÿ‘โ›”๏ธ5โ›”๏ธ
Repeaters๐Ÿ‘๐Ÿ‘3๐Ÿ‘
Solids๐Ÿ‘๐Ÿ‘3๐Ÿ‘

Footnotes

  1. Importing multiple images as frames โ†ฉ โ†ฉ2

  2. Conversion available as a Blender addon โ†ฉ โ†ฉ2

  3. Marked as unsupported โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4 โ†ฉ5 โ†ฉ6 โ†ฉ7 โ†ฉ8 โ†ฉ9 โ†ฉ10 โ†ฉ11 โ†ฉ12 โ†ฉ13 โ†ฉ14 โ†ฉ15

  4. Not listed as unsupported, maybe a bug? โ†ฉ

  5. Marked as unsuported but I haven't tested it โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4 โ†ฉ5 โ†ฉ6 โ†ฉ7 โ†ฉ8 โ†ฉ9

  6. Works on telegram desktop โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4 โ†ฉ5

  7. Note that python-lottie offers an alternative to lottie text layers, and can render text as shapes, so that is supported everywhere โ†ฉ