1try:
2 import numpy as np
3 import imageio
4except ImportError as e:
5 raise ImportError(
6 'Optional dependencies not installed. '
7 'Install with `python3 -m pip install "drawsvg[raster]"'
8 ) from e
9
10from .drawing import Drawing
11
12
13def render_svg_frames(frames, align_bottom=False, align_right=False,
14 bg=(255,)*4, **kwargs):
15 arr_frames = [imageio.imread(d.rasterize().pngData)
16 for d in frames]
17 max_width = max(map(lambda arr:arr.shape[1], arr_frames))
18 max_height = max(map(lambda arr:arr.shape[0], arr_frames))
19
20 def mod_frame(arr):
21 new_arr = np.zeros((max_height, max_width) + arr.shape[2:],
22 dtype=arr.dtype)
23 new_arr[:,:] = bg[:new_arr.shape[-1]]
24 if align_bottom:
25 slice0 = slice(-arr.shape[0], None)
26 else:
27 slice0 = slice(None, arr.shape[0])
28 if align_right:
29 slice1 = slice(-arr.shape[1], None)
30 else:
31 slice1 = slice(None, arr.shape[1])
32 new_arr[slice0, slice1] = arr
33 return new_arr
34 return list(map(mod_frame, arr_frames))
35
36def save_video(frames, file, **kwargs):
37 '''
38 Save a series of drawings as a GIF or video.
39
40 Arguments:
41 frames: A list of `Drawing`s or a list of `numpy.array`s.
42 file: File name or file like object to write the video to. The
43 extension determines the output format.
44 align_bottom: If frames are different sizes, align the bottoms of each
45 frame in the video.
46 align_right: If frames are different sizes, align the right edge of each
47 frame in the video.
48 bg: If frames are different sizes, fill the background with this color.
49 (default is white: (255, 255, 255, 255))
50 duration: If writing a GIF, sets the duration of each frame.
51 fps: If writing a video, sets the frame rate in FPS.
52 **kwargs: Other arguments to imageio.mimsave().
53
54 '''
55 if isinstance(frames[0], Drawing):
56 frames = render_svg_frames(frames, **kwargs)
57 kwargs.pop('align_bottom', None)
58 kwargs.pop('align_right', None)
59 kwargs.pop('bg', None)
60 imageio.mimsave(file, frames, **kwargs)