Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets
1import base64 2import io 3import warnings 4 5from .url_encode import bytes_as_data_uri 6 7try: 8 import cairosvg 9except OSError as e: 10 raise ImportError( 11 'Failed to load CairoSVG. ' 12 'drawSvg will be unable to output PNG or other raster image formats. ' 13 'See https://github.com/cduck/drawsvg#prerequisites for more details.' 14 ) from e 15except ImportError as e: 16 raise ImportError( 17 'CairoSVG will need to be installed to rasterize images. ' 18 'Install with `pip3 install cairosvg`.' 19 ) from e 20 21 22class Raster: 23 def __init__(self, png_data=None, png_file=None): 24 self.png_data = png_data 25 self.png_file = png_file 26 def save_png(self, fname): 27 with open(fname, 'wb') as f: 28 f.write(self.png_data) 29 @staticmethod 30 def from_svg(svg_data): 31 png_data = cairosvg.svg2png(bytestring=svg_data) 32 return Raster(png_data) 33 @staticmethod 34 def from_svg_to_file(svg_data, out_file): 35 cairosvg.svg2png(bytestring=svg_data, write_to=out_file) 36 return Raster(None, png_file=out_file) 37 def _repr_png_(self): 38 if self.png_data: 39 return self.png_data 40 elif self.png_file: 41 try: 42 with open(self.png_file, 'rb') as f: 43 return f.read() 44 except TypeError: 45 pass 46 try: 47 self.png_file.seek(0) 48 return self.png_file.read() 49 except io.UnsupportedOperation: 50 pass 51 def as_data_uri(self): 52 if self.png_data: 53 data = self.png_data 54 else: 55 try: 56 with open(self.png_file, 'rb') as f: 57 data = f.read() 58 except TypeError: 59 self.png_file.seek(0) 60 data = self.png_file.read() 61 return bytes_as_data_uri(data, mime='image/png')