Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets
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)