python-lottie  0.6.11+devcecd248
A framework to work with lottie files and telegram animated stickers (tgs)
gif.py
Go to the documentation of this file.
1 import io
2 from PIL import Image
3 from PIL import features
4 
5 from .cairo import PngRenderer
6 from .base import exporter, io_progress
7 from ..parsers.baseporter import ExtraOption
8 
9 
10 def _png_gif_prepare(image):
11  if image.mode not in ["RGBA", "RGBa"]:
12  image = image.convert("RGBA")
13  alpha = image.getchannel("A")
14  image = image.convert("RGB").convert('P', palette=Image.ADAPTIVE, colors=255)
15  mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
16  image.paste(255, mask=mask)
17  return image
18 
19 
20 def _log_frame(fmt, frame_no=None, end=None):
21  if frame_no is None:
22  io_progress().report_message("%s frame rendering completed" % (fmt))
23  else:
24  io_progress().report_progress("%s rendering frame" % fmt, frame_no, end)
25 
26 
27 @exporter("GIF", ["gif"], [
28  ExtraOption("skip_frames", type=int, default=1, help="Only renderer 1 out of these many frames"),
29 ])
30 def export_gif(animation, fp, dpi=96, skip_frames=1):
31  """
32  Gif export
33 
34  Note that it's a bit slow.
35  """
36  start = int(animation.in_point)
37  end = int(animation.out_point)
38  frames = []
39  with PngRenderer(animation, dpi) as renderer:
40  for i in range(start, end+1, skip_frames):
41  _log_frame("GIF", i, end)
42  file = io.BytesIO()
43  renderer.serialize(i, file)
44  file.seek(0)
45  frames.append(_png_gif_prepare(Image.open(file)))
46  _log_frame("GIF")
47 
48  io_progress().report_message("GIF Writing to file...")
49  duration = int(round(1000 / animation.frame_rate * skip_frames / 10)) * 10
50  frames[0].save(
51  fp,
52  format='GIF',
53  append_images=frames[1:],
54  save_all=True,
55  duration=duration,
56  loop=0,
57  transparency=255,
58  disposal=2,
59  )
60 
61 
62 @exporter("WebP", ["webp"], [
63  ExtraOption("lossless", action="store_true", help="If present, use lossless compression"),
64  ExtraOption("quality", type=int, default=80,
65  help="Compression effort between 0 and 100\n" +
66  "for lossy 0 gives the smallest size\n" +
67  "for lossless 0 gives the largest file"),
68  ExtraOption("method", type=int, default=0, help="Quality/speed trade-off (0=fast, 6=slower-better)"),
69  ExtraOption("skip_frames", type=int, default=1, help="Only renderer 1 out of these many frames"),
70 ])
71 def export_webp(animation, fp, dpi=96, lossless=False, quality=80, method=0, skip_frames=1):
72  """
73  Export WebP
74 
75  See https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#webp
76  """
77  if not features.check("webp_anim"):
78  raise Exception("WebP animations not supported in this system")
79 
80  start = int(animation.in_point)
81  end = int(animation.out_point)
82  frames = []
83  with PngRenderer(animation, dpi) as renderer:
84  for i in range(start, end+1, skip_frames):
85  _log_frame("WebP", i, end)
86  file = io.BytesIO()
87  renderer.serialize(i, file)
88  file.seek(0)
89  frames.append(Image.open(file))
90 
91  _log_frame("WebP")
92 
93  io_progress().report_message("WebP Writing to file...")
94  duration = int(round(1000 / animation.frame_rate * skip_frames))
95  frames[0].save(
96  fp,
97  format='WebP',
98  append_images=frames[1:],
99  save_all=True,
100  duration=duration,
101  loop=0,
102  background=(0, 0, 0, 0),
103  lossless=lossless,
104  quality=quality,
105  method=method
106  )
107 
108 
109 @exporter("TIFF", ["tiff"])
110 def export_tiff(animation, fp, dpi=96):
111  """
112  Export TIFF
113  """
114  start = int(animation.in_point)
115  end = int(animation.out_point)
116  frames = []
117  with PngRenderer(animation, dpi) as renderer:
118  for i in range(start, end+1):
119  _log_frame("TIFF", i, end)
120  file = io.BytesIO()
121  renderer.serialize(i, file)
122  file.seek(0)
123  frames.append(Image.open(file))
124  _log_frame("TIFF")
125 
126  io_progress().report_message("TIFF Writing to file...")
127  duration = int(round(1000 / animation.frame_rate))
128  frames[0].save(
129  fp,
130  format='TIFF',
131  append_images=frames[1:],
132  save_all=True,
133  duration=duration,
134  loop=0,
135  dpi=(dpi, dpi),
136  )
lottie.exporters.gif.export_gif
def export_gif(animation, fp, dpi=96, skip_frames=1)
Definition: gif.py:30
lottie.parsers.baseporter.ExtraOption
Definition: baseporter.py:32
lottie.exporters.gif.export_tiff
def export_tiff(animation, fp, dpi=96)
Definition: gif.py:110
lottie.exporters.base.exporter
exporter
Definition: base.py:32
lottie.parsers.glaxnimate_helpers.convert
def convert(animation, exporter_slug)
Definition: glaxnimate_helpers.py:11
lottie.exporters.gif.export_webp
def export_webp(animation, fp, dpi=96, lossless=False, quality=80, method=0, skip_frames=1)
Definition: gif.py:71
lottie.parsers.baseporter.io_progress
def io_progress()
Definition: baseporter.py:139
lottie.exporters.cairo.PngRenderer
Definition: cairo.py:40