def render(self): """ function to render figures """ # Svg // pdf render if self.ext in ('svg', 'pdf', 'eps', 'matplotlib'): #Convert pdf to svg if self.ext == 'pdf': figurein = convert_pdf_to_svg(self.content) elif self.ext == 'eps': figurein = convert_eps_to_svg(self.content) #Convert matplotlib figure to svg elif self.ext == 'matplotlib': #Store mpl svg to a stringIO object with StringIO() as tmpf: self.content.savefig(tmpf, bbox_inches='tight', format='svg') tmpf.seek(0) #go to the biginig of the file #store tmpf content as string in figurein variable figurein = tmpf.read().encode('utf-8') #General case for svg format else: #Check if a filename is given for a svg file or directly read the content value if os.path.isfile(self.content): with open(self.content, 'r') as f: figurein = f.read() else: figurein = self.content #test if we need to optimise the svg if document._optimize_svg: figurein = optimize_svg(figurein) soup = BeautifulSoup(figurein, 'xml') #Change id in svg defs to use the global id system soup = make_global_svg_defs(soup) #Optimize the size of embeded svg images ! if document._resize_raster: imgs = soup.findAll('image') if imgs: for img in imgs: #True width and height of embed svg image width, height = int(float(img['width'])), int( float(img['height'])) img_ratio = height / float(width) b64content = img['xlink:href'] try: in_img = BytesIO( base64.b64decode( b64content.split(';base64,')[1])) tmp_img = Image.open(in_img) #print(tmp_img) out_img = resize_raster_image( tmp_img, max_width=self.positionner.width.value) out_b64 = base64.b64encode( out_img.read()).decode('utf8') #replace the resized image into the svg img['xlink:href'] = 'data:image/%s;base64, %s' % ( tmp_img.format.lower(), out_b64) except: print('Unable to reduce the image size') pass svgtag = soup.find('svg') svg_viewbox = svgtag.get("viewBox") tmph = svgtag.get("height") tmpw = svgtag.get("width") if tmph is None or tmpw is None: with tempfile.NamedTemporaryFile(mode='w', prefix='beampytmp', suffix='.svg') as f: try: f.write(figurein) except Exception as e: #python 2 f.write(figurein.encode('utf8')) # force to write file content to disk f.file.flush() # get svg size using inkscape tmph = getsvgheight(f.name) tmpw = getsvgwidth(f.name) svgheight = convert_unit(tmph) svgwidth = convert_unit(tmpw) if svg_viewbox is not None: svgheight = svg_viewbox.split(' ')[3] svgwidth = svg_viewbox.split(' ')[2] # BS4 get the svg tag content without <svg> and </svg> tmpfig = svgtag.renderContents().decode('utf8') # Scale the figure according to the given width if self.width.value is not None and self.height.value is None: # SCALE OK need to keep the original viewBox !!! scale = (self.positionner.width / float(svgwidth)).value figure_height = float(svgheight) * scale figure_width = self.positionner.width.value # Scale the figure according to the given height if self.height.value is not None and self.width.value is None: figure_height = self.positionner.height.value scale = (self.positionner.height / float(svgheight)).value figure_width = float(svgwidth) * scale # Dont scale the figure let the user fix the width height if self.height.value is not None and self.width.value is not None: output = tmpfig figure_height = self.positionner.height.value figure_width = self.positionner.width.value else: # Apply the scaling to the figure tmphead = '\n<g transform="scale(%0.5f)">' % (scale) output = tmphead + tmpfig + '</g>\n' #Update the final svg size self.update_size(figure_width, figure_height) #Add the final svg output of the figure self.svgout = output #Bokeh images if self.ext == 'bokeh': # Change the sizing mode (need scale_both) to adapt size of the figure self.content.sizing_mode = 'scale_both' # Run the bokeh components function to separate figure html div and js script figscript, figdiv = components(self.content, wrap_script=False) # Transform figscript to givea function name load_bokehjs tmp = figscript.splitlines() goodscript = '\n'.join(['["load_bokeh"] = function() {'] + tmp[1:-1] + ['};\n']) #Add the htmldiv to htmlout self.htmlout = "<div id='bk_resizer' width='{width}px' height='{height}px' style='width: {width}px; height: {height}px; transform-origin: left top 0px;'> {html} </div>" self.htmlout = self.htmlout.format(width=self.positionner.width, height=self.positionner.height, html=figdiv) #Add the script to scriptout self.jsout = goodscript #For the other format if self.ext in ('png', 'jpeg', 'gif'): #Open image with PIL to compute size tmp_img = Image.open(self.content) _, _, tmpwidth, tmpheight = tmp_img.getbbox() # Scale the figure according to the given width if self.width.value is not None and self.height.value is None: # SCALE OK need to keep the original viewBox !!! scale = (self.positionner.width / float(tmpwidth)).value figure_height = float(tmpheight) * scale figure_width = self.positionner.width.value # Scale the figure according to the given height if self.height.value is not None and self.width.value is None: figure_height = self.positionner.height.value scale = (self.positionner.height / float(tmpheight)).value figure_width = float(tmpwidth) * scale # Dont scale the figure let the user fix the width height if self.height.value is not None and self.width.value is not None: figure_height = self.positionner.height.value figure_width = self.positionner.width.value if document._resize_raster: #Rescale figure to the good size (to improve size and display speed) if self.ext == 'gif': print('Gif are not resized, the original size is taken!') with open(self.content, "rb") as f: figurein = base64.b64encode(f.read()).decode('utf8') else: out_img = resize_raster_image(tmp_img, max_width=figure_width) figurein = base64.b64encode(out_img.read()).decode('utf8') out_img.close() else: with open(self.content, "rb") as f: figurein = base64.b64encode(f.read()).decode('utf8') tmp_img.close() if self.ext == 'png': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/png;base64, %s" />' % ( figure_width, figure_height, figurein) if self.ext == 'jpeg': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/jpg;base64, %s" />' % ( figure_width, figure_height, figurein) if self.ext == 'gif': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/gif;base64, %s" />' % ( figure_width, figure_height, figurein) # Update the final size of the figure self.update_size(figure_width, figure_height) # Add the final svg to svgout self.svgout = output #print self.width, self.height #Update the rendered state of the module self.rendered = True
def render(self): """ function to render figures """ #Svg // pdf render if self.ext in ('svg', 'pdf') : #Convert pdf to svg if self.ext == 'pdf' : figurein = convert_pdf_to_svg( self.content ) else: #Check if a filename is given for a svg file or directly read the content value if os.path.isfile(self.content): with open(self.content) as f: figurein = f.read() else: figurein = self.content #test if we need to optimise the svg if document._optimize_svg: figurein = optimize_svg(figurein) soup = BeautifulSoup(figurein, 'xml') #Change id in svg defs to use the global id system soup = make_global_svg_defs(soup) #Optimize the size of embeded svg images ! if document._resize_raster: imgs = soup.findAll('image') if imgs: for img in imgs: #True width and height of embed svg image width, height = int( float(img['width']) ) , int( float(img['height']) ) img_ratio = height/float(width) b64content = img['xlink:href'] try: in_img = BytesIO( base64.b64decode(b64content.split(';base64,')[1]) ) tmp_img = Image.open(in_img) #print(tmp_img) out_img = resize_raster_image( tmp_img ) out_b64 = base64.b64encode( out_img.read() ) #replace the resized image into the svg img['xlink:href'] = 'data:image/%s;base64, %s'%(tmp_img.format.lower(), out_b64) except: print('Unable to reduce the image size') pass svgtag = soup.find('svg') svg_viewbox = svgtag.get("viewBox") tmph = svgtag.get("height") tmpw = svgtag.get("width") if tmph == None or tmpw == None: fmpf, tmpname = tempfile.mkstemp(prefix="beampytmp") with open( tmpname+'.svg', 'w' ) as f: f.write(figurein) #print figurein tmph = getsvgheight( tmpname+'.svg' ) tmpw = getsvgwidth( tmpname+'.svg' ) #print tmpw, tmph os.remove(tmpname+'.svg') svgheight = convert_unit( tmph ) svgwidth = convert_unit( tmpw ) if svg_viewbox != None: svgheight = svg_viewbox.split(' ')[3] svgwidth = svg_viewbox.split(' ')[2] #SCALE OK need to keep the original viewBox !!! scale_x = self.positionner.width/float(svgwidth) #print svgwidth, svgheight, scale_x #scale_y = float(convert_unit(args['height']))/float(svgheight) good_scale = scale_x #BS4 get the svg tag content without <svg> and </svg> tmpfig = svgtag.renderContents() #Add the correct first line and last tmphead = '\n<g transform="scale(%0.5f)">'%(good_scale) output = tmphead + tmpfig + '</g>\n' figure_height = float(svgheight)*good_scale figure_width = self.width #Update the final svg size self.update_size(figure_width, figure_height) #Add the final svg output of the figure self.svgout = output #Bokeh images if self.ext == 'bokeh': #Run the bokeh components function to separate figure html div and js script figscript, figdiv = components(self.content, wrap_script=False) #Transform figscript to givea function name load_bokehjs tmp = figscript.splitlines() goodscript = '\n'.join( ['["load_bokeh"] = function() {'] + tmp[1:-1] + ['};\n'] ) #Add the htmldiv to htmlout self.htmlout = figdiv #Add the script to scriptout self.jsout = goodscript #For the other format if self.ext in ('png', 'jpeg'): #Open image with PIL to compute size tmp_img = Image.open(self.content) _,_,tmpwidth,tmpheight = tmp_img.getbbox() scale_x = self.positionner.width/float(tmpwidth) figure_height = float(tmpheight) * scale_x figure_width = self.positionner.width if document._resize_raster: #Rescale figure to the good size (to improve size and display speed) out_img = resize_raster_image(tmp_img) figurein = base64.b64encode(out_img.read()) out_img.close() else: with open( self.content, "r") as f: figurein = base64.b64encode(f.read()) tmp_img.close() if self.ext == 'png': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/png;base64, %s" />'%(figure_width, figure_height, figurein) if self.ext == 'jpeg': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/jpg;base64, %s" />'%(figure_width, figure_height, figurein) #Update the final size of the figure self.update_size(figure_width, figure_height) #Add the final svg to svgout self.svgout = output #print self.width, self.height #Update the rendered state of the module self.rendered = True
def render_figure( ct ): """ function to render figures """ #read args in the dict args = ct['args'] #Svg // pdf render if args['ext'] in ('svg', 'pdf') : #Convert pdf to svg if args['ext'] == 'pdf' : figurein = convert_pdf_to_svg( args['filename'] ) else: #Check if a filename is given for a svg file or directly read the content value if 'filename' in args: with open(args['filename']) as f: figurein = f.read() else: figurein = ct['content'] #test if we need to optimise the svg if document._optimize_svg: figurein = optimize_svg(figurein) soup = BeautifulSoup(figurein, 'xml') #Change id in svg defs to use the global id system soup = make_global_svg_defs(soup) #Optimize the size of embeded svg images ! if document._resize_raster: imgs = soup.findAll('image') if imgs: for img in imgs: #True width and height of embed svg image width, height = int( float(img['width']) ) , int( float(img['height']) ) img_ratio = height/float(width) b64content = img['xlink:href'] try: in_img = BytesIO( base64.b64decode(b64content.split(';base64,')[1]) ) tmp_img = Image.open(in_img) #print(tmp_img) out_img = resize_raster_image( tmp_img ) out_b64 = base64.b64encode( out_img.read() ) #replace the resized image into the svg img['xlink:href'] = 'data:image/%s;base64, %s'%(tmp_img.format.lower(), out_b64) except: print('Unable to reduce the image size') pass svgtag = soup.find('svg') svg_viewbox = svgtag.get("viewBox") tmph = svgtag.get("height") tmpw = svgtag.get("width") if tmph == None or tmpw == None: fmpf, tmpname = tempfile.mkstemp(prefix="beampytmp") with open( tmpname+'.svg', 'w' ) as f: f.write(figurein) #print figurein tmph = getsvgheight( tmpname+'.svg' ) tmpw = getsvgwidth( tmpname+'.svg' ) #print tmpw, tmph os.remove(tmpname+'.svg') svgheight = convert_unit( tmph ) svgwidth = convert_unit( tmpw ) if svg_viewbox != None: svgheight = svg_viewbox.split(' ')[3] svgwidth = svg_viewbox.split(' ')[2] #SCALE OK need to keep the original viewBox !!! scale_x = ct['positionner'].width/float(svgwidth) #print svgwidth, svgheight, scale_x #scale_y = float(convert_unit(args['height']))/float(svgheight) good_scale = scale_x #BS4 get the svg tag content without <svg> and </svg> tmpfig = svgtag.renderContents() #print tmpfig[:100] #Add the correct first line and last #tmphead = '<g transform="matrix(%s,0,0,%s,%s,%s)" viewBox="%s">'%(str(good_scale), str(good_scale), convert_unit(args['x']), convert_unit(args['y']), svg_viewbox)) tmphead = '\n<g transform="scale(%0.5f)">'%(good_scale) output = tmphead + tmpfig + '</g>\n' figure_height = float(svgheight)*good_scale figure_width = ct['positionner'].width #Bokeh images if args['ext'] == 'bokeh': figurein = ct['content'] figure_height = ct['positionner'].height figure_width = ct['positionner'].width output = """%s"""%figurein #For the other format if args['ext'] in ['png', 'jpeg']: #Open image with PIL to compute size tmp_img = Image.open(args['filename']) _,_,tmpwidth,tmpheight = tmp_img.getbbox() scale_x = ct['positionner'].width/float(tmpwidth) figure_height = float(tmpheight) * scale_x figure_width = ct['positionner'].width if document._resize_raster: #Rescale figure to the good size (to improve size and display speed) out_img = resize_raster_image(tmp_img) figurein = base64.b64encode(out_img.read()) out_img.close() else: with open( args['filename'], "r") as f: figurein = base64.b64encode(f.read()) tmp_img.close() if args['ext'] == 'png': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/png;base64, %s" />'%(figure_width, figure_height, figurein) if args['ext'] == 'jpeg': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/jpg;base64, %s" />'%(figure_width, figure_height, figurein) ct['positionner'].update_size(figure_width, figure_height) return output
def render(self): """ function to render figures """ #Svg // pdf render if self.ext in ('svg', 'pdf', 'matplotlib') : #Convert pdf to svg if self.ext == 'pdf' : figurein = convert_pdf_to_svg( self.content ) #Convert matplotlib figure to svg elif self.ext == 'matplotlib': #Store mpl svg to a stringIO object with StringIO() as tmpf: self.content.savefig(tmpf, bbox_inches='tight', format='svg') tmpf.seek(0) #go to the biginig of the file #store tmpf content as string in figurein variable figurein = tmpf.read().encode('utf-8') #General case for svg format else: #Check if a filename is given for a svg file or directly read the content value if os.path.isfile(self.content): with open(self.content) as f: figurein = f.read() else: figurein = self.content #test if we need to optimise the svg if document._optimize_svg: figurein = optimize_svg(figurein) soup = BeautifulSoup(figurein, 'xml') #Change id in svg defs to use the global id system soup = make_global_svg_defs(soup) #Optimize the size of embeded svg images ! if document._resize_raster: imgs = soup.findAll('image') if imgs: for img in imgs: #True width and height of embed svg image width, height = int( float(img['width']) ) , int( float(img['height']) ) img_ratio = height/float(width) b64content = img['xlink:href'] try: in_img = BytesIO( base64.b64decode(b64content.split(';base64,')[1]) ) tmp_img = Image.open(in_img) #print(tmp_img) out_img = resize_raster_image( tmp_img ) out_b64 = base64.b64encode( out_img.read() ) #replace the resized image into the svg img['xlink:href'] = 'data:image/%s;base64, %s'%(tmp_img.format.lower(), out_b64) except: print('Unable to reduce the image size') pass svgtag = soup.find('svg') svg_viewbox = svgtag.get("viewBox") tmph = svgtag.get("height") tmpw = svgtag.get("width") if tmph == None or tmpw == None: fmpf, tmpname = tempfile.mkstemp(prefix="beampytmp") with open( tmpname+'.svg', 'w' ) as f: f.write(figurein) #print figurein tmph = getsvgheight( tmpname+'.svg' ) tmpw = getsvgwidth( tmpname+'.svg' ) #print tmpw, tmph os.remove(tmpname+'.svg') svgheight = convert_unit( tmph ) svgwidth = convert_unit( tmpw ) if svg_viewbox != None: svgheight = svg_viewbox.split(' ')[3] svgwidth = svg_viewbox.split(' ')[2] #SCALE OK need to keep the original viewBox !!! scale_x = self.positionner.width/float(svgwidth) #print svgwidth, svgheight, scale_x #scale_y = float(convert_unit(args['height']))/float(svgheight) good_scale = scale_x #BS4 get the svg tag content without <svg> and </svg> tmpfig = svgtag.renderContents() #Add the correct first line and last tmphead = '\n<g transform="scale(%0.5f)">'%(good_scale) output = tmphead + tmpfig + '</g>\n' figure_height = float(svgheight)*good_scale figure_width = self.width #Update the final svg size self.update_size(figure_width, figure_height) #Add the final svg output of the figure self.svgout = output #Bokeh images if self.ext == 'bokeh': # Run the bokeh components function to separate figure html div and js script figscript, figdiv = components(self.content, wrap_script=False) # Transform figscript to givea function name load_bokehjs tmp = figscript.splitlines() goodscript = '\n'.join( ['["load_bokeh"] = function() {'] + tmp[1:-1] + ['};\n'] ) #Add the htmldiv to htmlout self.htmlout = figdiv #Add the script to scriptout self.jsout = goodscript #For the other format if self.ext in ('png', 'jpeg'): #Open image with PIL to compute size tmp_img = Image.open(self.content) _,_,tmpwidth,tmpheight = tmp_img.getbbox() scale_x = self.positionner.width/float(tmpwidth) figure_height = float(tmpheight) * scale_x figure_width = self.positionner.width if document._resize_raster: #Rescale figure to the good size (to improve size and display speed) out_img = resize_raster_image(tmp_img) figurein = base64.b64encode(out_img.read()) out_img.close() else: with open( self.content, "r") as f: figurein = base64.b64encode(f.read()) tmp_img.close() if self.ext == 'png': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/png;base64, %s" />'%(figure_width, figure_height, figurein) if self.ext == 'jpeg': output = '<image x="0" y="0" width="%s" height="%s" xlink:href="data:image/jpg;base64, %s" />'%(figure_width, figure_height, figurein) #Update the final size of the figure self.update_size(figure_width, figure_height) #Add the final svg to svgout self.svgout = output #print self.width, self.height #Update the rendered state of the module self.rendered = True
def figure(filename,x='center',y='auto', width=None, height=None, ext=None): """ Add figure to current slide Accepted format: [svg, png, jpeg, bokeh figure] - x['center']: x coordinate of the image 'center': center image relative to document._width '+1cm": place image relative to previous element - y['auto']: y coordinate of the image 'auto': distribute all slide element on document._height 'center': center image relative to document._height (ignore other slide elements) '+3cm': place image relative to previous element - width[None]: Image width, if None: width = document._width - height[None]: Image heigt - ext[None]: Image format, if None, format is guessed from filename. """ #Check if the given filename is a string if type(filename) == type(''): #Check extension if ext == None: if '.svg' in filename.lower(): ext = 'svg' if '.png' in filename.lower(): ext = 'png' if ( '.jpeg' in filename.lower() ) or ( '.jpg' in filename.lower() ): ext = 'jpeg' if '.pdf' in filename.lower(): ext = 'pdf' else: if "bokeh" in str(type(filename)): ext = 'bokeh' ###################################### if ext == None: print("figure format can't be guessed from file name") #Bokeh image elif ext == 'bokeh': #print('I got a bokeh figure') figscript, figdiv = components(filename, wrap_script=False) #Todo get width and height from a bokeh figure if width == None: width = '%ipx'%filename.plot_width if height == None: height = '%ipx'%filename.plot_height #Transform figscript to givea function name load_bokehjs tmp = figscript.splitlines() goodscript = '\n'.join( ['["load_bokeh"] = function() {'] + tmp[1:-1] + ['};\n'] ) args = {"x":str(x), "y": str(y) , "width": str(width), "height": str(height), "ext": ext, 'script':goodscript} figout = {'type': 'html', 'content': figdiv, 'args': args, 'render': render_figure} document._contents[gcs()]['contents'] += [ figout ] #Other filetype images else: if width == None: width = str(document._width) else: width = str(width) if height != None: height = str(height) args = {"x":str(x), "y": str(y) , "width": width, "height": height, "ext": ext, 'filename':filename } if ext == 'pdf' : figdata = convert_pdf_to_svg( filename ) else : with open(filename,"r") as f: figdata = f.read() #If it's png/jpeg figure we need to encode them to base64 if ext in ( 'png', 'jpeg' ): figdata = base64.encodestring(figdata) figout = {'type': 'figure', 'content': figdata, 'args': args, "render": render_figure} document._contents[gcs()]['contents'] += [ figout ]