python-lottie  0.6.11+devcecd248
A framework to work with lottie files and telegram animated stickers (tgs)
raster.py
Go to the documentation of this file.
1 from PIL import Image
2 import glaxnimate
3 from . import glaxnimate_helpers
4 import enum
5 from .. import objects
6 from ..nvector import NVector
7 from .pixel import _vectorizing_func
8 
9 
10 class QuanzationMode(enum.Enum):
11  Nearest = 1
12  Exact = 2
13 
14 
16  def get_colors(self, image, n_colors):
17  pass
18 
19 
20 class KMeansPalette(PaletteAlgorithm):
21  def __init__(self, iterations=100, match=glaxnimate.utils.quantize.MatchType.MostFrequent):
22  self.iterations = iterations
23  self.match = match
24 
25  def get_colors(self, image, n_colors):
26  return glaxnimate.utils.quantize.k_means(image, n_colors, self.iterations, self.match)
27 
28 
30  def get_colors(self, image, n_colors):
31  return glaxnimate.utils.quantize.octree(image, n_colors)
32 
33 
35  def get_colors(self, image, n_colors):
36  return glaxnimate.utils.quantize.k_modes(image, n_colors)
37 
38 
40  def __init__(self, color_mode=QuanzationMode.Nearest, palette_algorithm=OctreePalette(), tolerance=100, stroke_width=1):
41  self.trace_options = glaxnimate.utils.trace.TraceOptions()
42  self.palette_algorithm = palette_algorithm
43  self.color_mode = color_mode
44  self.tolerance = tolerance
45  self.stroke_width = stroke_width
46 
47  @property
48  def smoothness(self):
49  return self.trace_options.smoothness
50 
51  @smoothness.setter
52  def smoothness(self, value):
53  self.trace_options.smoothness = value
54 
55  @property
56  def min_area(self):
57  return self.trace_options.min_area
58 
59  @min_area.setter
60  def min_area(self, value):
61  self.trace_options.min_area = value
62 
63  def quantize(self, image, n_colors):
64  """!
65  Returns a list of RGB values
66  """
67  return self.palette_algorithm.get_colors(image, n_colors)
68 
69  def trace(self, image, codebook):
70  """!
71  Returns a list of tuple [color, data] where for each color in codebook
72  data is a list of bezier
73 
74  You can get codebook from quantize()
75  """
76 
77  if codebook is None or len(codebook) == 0:
78  tracer = glaxnimate.utils.trace.Tracer(image, self.trace_options)
79  tracer.set_target_alpha(128, False)
80  return [glaxnimate.utils.Color(0, 0, 0), tracer.trace()]
81 
82  if self.color_mode == QuanzationMode.Nearest:
83  return list(zip(codebook, glaxnimate.utils.trace.quantize_and_trace(image, self.trace_options, codebook)))
84 
85  mono_data = []
86  tracer = glaxnimate.utils.trace.Tracer(image, self.trace_options)
87  for color in codebook:
88  tracer.set_target_color(color, self.tolerance)
89  mono_data.append((color, tracer.trace()))
90 
91  return mono_data
92 
93 
94 class Vectorizer:
95  def __init__(self, trace_options: TraceOptions):
96  self.palette = None
97  self.layers = {}
98  self.trace_options = trace_options
99 
100  def _create_layer(self, animation, layer_name):
101  layer = animation.add_layer(objects.ShapeLayer())
102  if layer_name:
103  self.layers[layer_name] = layer
104  layer.name = layer_name
105  return layer
106 
107  def prepare_layer(self, animation, layer_name=None):
108  layer = self._create_layer(animation, layer_name)
109  layer._max_verts = {}
110  for color in self.palette:
111  group = layer.add_shape(objects.Group())
112  group.name = "color_%s" % color.name
113  layer._max_verts[group.name] = 0
114  fcol = glaxnimate_helpers.color_from_glaxnimate(color)
115  group.add_shape(objects.Fill(NVector(*fcol)))
116  if self.trace_options.stroke_width > 0:
117  group.add_shape(objects.Stroke(NVector(*fcol), self.trace_options.stroke_width))
118  return layer
119 
120  def raster_to_layer(self, animation, raster, layer_name=None):
121  layer = self.prepare_layer(animation, layer_name)
122  mono_data = self.trace_options.trace(raster, self.palette)
123  for (color, beziers), group in zip(mono_data, layer.shapes):
124  self.traced_to_shapes(group, beziers)
125  return layer
126 
127  def traced_to_shapes(self, group, beziers):
128  shapes = []
129  for bezier in beziers:
130  shape = group.insert_shape(0, objects.Path())
131  shapes.append(shape)
132  shape.shape.value = self.traced_to_bezier(bezier)
133  return shapes
134 
135  def traced_to_bezier(self, path):
136  bezier = objects.Bezier()
137  for point in path:
138  pos = glaxnimate_helpers.point_from_glaxnimate(point.pos)
139  tan_in = glaxnimate_helpers.point_from_glaxnimate(point.tan_in - point.pos)
140  tan_out = glaxnimate_helpers.point_from_glaxnimate(point.tan_out - point.pos)
141  bezier.add_point(pos, tan_in, tan_out)
142  if path.closed:
143  bezier.closed = True
144  return bezier
145 
146 
148  filenames,
149  n_colors=1,
150  frame_delay=1,
151  framerate=60,
152  palette=[],
153  trace_options=TraceOptions()
154 ):
155  vc = Vectorizer(trace_options)
156 
157  def callback(animation, raster, frame, time, duration):
158  if vc.palette is None:
159  if palette:
160  vc.palette = [glaxnimate_helpers.color_to_glaxnimate(c) for c in palette]
161  elif n_colors > 1:
162  vc.palette = trace_options.quantize(raster, n_colors)
163  else:
164  vc.palette = [glaxnimate.utils.Color(0, 0, 0, 255)]
165  layer = vc.raster_to_layer(animation, raster, "frame_%s" % frame)
166  layer.in_point = time
167  layer.out_point = layer.in_point + duration
168 
169  animation = _vectorizing_func(filenames, frame_delay, framerate, callback)
170 
171  return animation
lottie.objects.shapes.Group
ShapeElement that can contain other shapes.
Definition: shapes.py:430
lottie.parsers.raster.TraceOptions.__init__
def __init__(self, color_mode=QuanzationMode.Nearest, palette_algorithm=OctreePalette(), tolerance=100, stroke_width=1)
Definition: raster.py:40
lottie.parsers.raster.KMeansPalette.iterations
iterations
Definition: raster.py:22
lottie.parsers.raster.Vectorizer
Definition: raster.py:94
lottie.parsers.raster.Vectorizer.prepare_layer
def prepare_layer(self, animation, layer_name=None)
Definition: raster.py:107
lottie.objects.shapes.Stroke
Solid stroke.
Definition: shapes.py:648
lottie.parsers.raster.KMeansPalette.__init__
def __init__(self, iterations=100, match=glaxnimate.utils.quantize.MatchType.MostFrequent)
Definition: raster.py:21
lottie.parsers.raster.QuanzationMode
Definition: raster.py:10
lottie.parsers.raster.Vectorizer.palette
palette
Definition: raster.py:96
lottie.objects.bezier.Bezier
Single bezier curve.
Definition: bezier.py:123
lottie.parsers.raster.Vectorizer._create_layer
def _create_layer(self, animation, layer_name)
Definition: raster.py:100
lottie.parsers.raster.Vectorizer.raster_to_layer
def raster_to_layer(self, animation, raster, layer_name=None)
Definition: raster.py:120
lottie.parsers.raster.raster_to_animation
def raster_to_animation(filenames, n_colors=1, frame_delay=1, framerate=60, palette=[], trace_options=TraceOptions())
Definition: raster.py:147
lottie.parsers.raster.TraceOptions.smoothness
def smoothness(self)
Definition: raster.py:48
lottie.parsers.raster.OctreePalette
Definition: raster.py:29
lottie.objects.shapes.Path
Animatable Bezier curve.
Definition: shapes.py:398
lottie.parsers.raster.Vectorizer.layers
layers
Definition: raster.py:97
lottie.parsers.raster.TraceOptions.trace
def trace(self, image, codebook)
Returns a list of tuple [color, data] where for each color in codebook data is a list of bezier.
Definition: raster.py:69
lottie.parsers.raster.Vectorizer.traced_to_shapes
def traced_to_shapes(self, group, beziers)
Definition: raster.py:127
lottie.objects.shapes.Fill
Solid fill color.
Definition: shapes.py:506
lottie.parsers.raster.KModesPalette.get_colors
def get_colors(self, image, n_colors)
Definition: raster.py:35
lottie.parsers.raster.TraceOptions.color_mode
color_mode
Definition: raster.py:43
lottie.parsers.raster.Vectorizer.__init__
def __init__(self, TraceOptions trace_options)
Definition: raster.py:95
lottie.parsers.raster.TraceOptions.min_area
def min_area(self)
Definition: raster.py:56
lottie.parsers.raster.TraceOptions
Definition: raster.py:39
lottie.parsers.raster.TraceOptions.palette_algorithm
palette_algorithm
Definition: raster.py:42
lottie.parsers.raster.KMeansPalette.get_colors
def get_colors(self, image, n_colors)
Definition: raster.py:25
lottie.parsers.raster.OctreePalette.get_colors
def get_colors(self, image, n_colors)
Definition: raster.py:30
lottie.parsers.raster.KMeansPalette.match
match
Definition: raster.py:23
lottie.parsers.raster.PaletteAlgorithm.get_colors
def get_colors(self, image, n_colors)
Definition: raster.py:16
lottie.parsers.raster.KModesPalette
Definition: raster.py:34
lottie.parsers.raster.PaletteAlgorithm
Definition: raster.py:15
lottie.parsers.raster.Vectorizer.trace_options
trace_options
Definition: raster.py:98
lottie.parsers.raster.TraceOptions.trace_options
trace_options
Definition: raster.py:41
lottie.parsers.raster.TraceOptions.stroke_width
stroke_width
Definition: raster.py:45
lottie.parsers.raster.Vectorizer.traced_to_bezier
def traced_to_bezier(self, path)
Definition: raster.py:135
lottie.parsers.raster.TraceOptions.quantize
def quantize(self, image, n_colors)
Returns a list of RGB values.
Definition: raster.py:63
lottie.parsers.raster.TraceOptions.tolerance
tolerance
Definition: raster.py:44
lottie.nvector.NVector
Definition: nvector.py:9
lottie.objects.layers.ShapeLayer
Layer containing ShapeElement objects.
Definition: layers.py:192