Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets
1 2import base64 3import io 4import warnings 5from .missing import MissingModule 6 7 8try: 9 import cairosvg 10except OSError as e: 11 msg = ( 12 'Failed to import CairoSVG. ' 13 'drawSvg will be unable to output PNG or other raster image formats. ' 14 'See https://github.com/cduck/drawSvg#prerequisites for more details.\n' 15 'Original OSError: {}'.format(e) 16 ) 17 cairosvg = MissingModule(msg) 18 warnings.warn(msg, RuntimeWarning) 19except ImportError as e: 20 msg = ( 21 'CairoSVG will need to be installed to rasterize images: Install with `pip3 install cairosvg`\n' 22 'Original ImportError: {}'.format(e) 23 ) 24 cairosvg = MissingModule(msg) 25 warnings.warn(msg, RuntimeWarning) 26 27 28class Raster: 29 def __init__(self, pngData=None, pngFile=None): 30 self.pngData = pngData 31 self.pngFile = pngFile 32 def savePng(self, fname): 33 with open(fname, 'wb') as f: 34 f.write(self.pngData) 35 @staticmethod 36 def fromSvg(svgData): 37 pngData = cairosvg.svg2png(bytestring=svgData) 38 return Raster(pngData) 39 @staticmethod 40 def fromSvgToFile(svgData, outFile): 41 cairosvg.svg2png(bytestring=svgData, write_to=outFile) 42 return Raster(None, pngFile=outFile) 43 def _repr_png_(self): 44 if self.pngData: 45 return self.pngData 46 elif self.pngFile: 47 try: 48 with open(self.pngFile, 'rb') as f: 49 return f.read() 50 except TypeError: 51 pass 52 try: 53 self.pngFile.seek(0) 54 return self.pngFile.read() 55 except io.UnsupportedOperation: 56 pass 57 def asDataUri(self): 58 if self.pngData: 59 data = self.pngData 60 else: 61 try: 62 with open(self.pngFile, 'rb') as f: 63 data = f.read() 64 except TypeError: 65 self.pngFile.seek(0) 66 data = self.pngFile.read() 67 b64 = base64.b64encode(data) 68 return 'data:image/png;base64,' + b64.decode(encoding='ascii')