Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting .SVG images into tkinter Frame

I have been trying to put the image from https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg into a Tkinter frame. I found from the post here that it is possible with the help from rsvg and cairo.

I was using python 3.6 on Windows 10. I got rsvg from here and cairo from here and then extracted the folders to the 'C:\Users...\site_packages' folder. They import fine but I cannot figure out how to use them. I tried using the code:

import tkinter as tk
main=tk.Tk()
frame=tk.Frame(main)
def svgPhotoImage(self,file_path_name):
        from PIL import Image,ImageTk
        import rsvg,cairo 
        svg = rsvg.Handle(file=file_path_name)
        width, height = svg.get_dimension_data()[:2]
            surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
            context = cairo.Context(surface)
            #context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
            svg.render_cairo(context)
            tk_image=ImageTk.PhotoImage('RGBA')
            image=Image.frombuffer('RGBA',(width,height),surface.get_data(),'raw','BGRA',0,1)
            tk_image.paste(image)
            return(tk_image)
    tk_image=self.svgPhotoImage(filename)
    frame.configure(image=tk_image)

and

#rsvg.py
import os
try:
    import rsvg
    WINDOWS=False
except ImportError:
    print"Warning, could not import 'rsvg'"
    if os.name == 'nt':
        print "Detected windows, creating rsvg."
        #some workarounds for windows

        from ctypes import *

        l=CDLL('librsvg-2-2.dll')
        g=CDLL('libgobject-2.0-0.dll')
        g.g_type_init()

        class rsvgHandle():
            class RsvgDimensionData(Structure):
                _fields_ = [("width", c_int),
                            ("height", c_int),
                            ("em",c_double),
                            ("ex",c_double)]

            class PycairoContext(Structure):
                _fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
                            ("ctx", c_void_p),
                            ("base", c_void_p)]

            def __init__(self, path):
                self.path = path
                error = ''
                self.handle = l.rsvg_handle_new_from_file(self.path,error)


            def get_dimension_data(self):
                svgDim = self.RsvgDimensionData()
                l.rsvg_handle_get_dimensions(self.handle,byref(svgDim))
                return (svgDim.width,svgDim.height)

            def render_cairo(self, ctx):
                ctx.save()
                z = self.PycairoContext.from_address(id(ctx))
                l.rsvg_handle_render_cairo(self.handle, z.ctx)
                ctx.restore()



        class rsvgClass():
            def Handle(self,file):
                return rsvgHandle(file)

        rsvg = rsvgClass()).
h = rsvg.Handle("box.svg")
s = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
ctx = cairo.Context(s)
h.render_cairo(ctx)

After trying those scripts, I kept getting the error message:

AttributeError: module 'rsvg' has no attribute 'Handle'

I am sure I did something wrong in the process but after hours of searching still could not figure out how to get it to work. I also tried installing pycairo (via pip) but got the error message

ERROR: Command "'c:\...\python36-32\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\...\\pip-install-peqhj3x1\\pycairo\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\...\Temp\pip-record-jfozfbuc\install-record.txt' --single-version-externally-managed --compile" failed with error code 1 in C:\...\pip-install-peqhj3x1\pycairo\

I have no clue as to what to do now

EDIT: I was finally able to obtain pycairo from https://www.lfd.uci.edu/~gohlke/pythonlibs/ and now have it working. I finally got rsvg to not give me the error message above by referring here and got the nessary DLL files from here. Cairo is working fine but RSVG is creating a blank screen. I tried another 7-liner here and get the output of a blank file instead of a converted one. Evidently RSVG is not working and I think it is an installation issue (eg. incorrect .dll's). Help?

If am trying to use cairo and rsvg because they take up little space and are really fast; wand or some other library is not an option. I just want to be able to put an SVG file into a tkinter frame. If anyone knows how install rsvg properly, I'd appreciate knowing.

Any help would be hugely appreciated. Thank you for any suggestions.

like image 334
Andoo Avatar asked May 01 '19 22:05

Andoo


People also ask

Can tkinter display SVG?

You can show SVG with this script into TKINTER!

Can you import images into tkinter?

Image can be added with the help of PhotoImage() method. This is a Tkinter method which means you don't have to import any other module in order to use it.


1 Answers

I've managed to do it using svglib:

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF, renderPM

drawing = svg2rlg("safari-pinned-tab.f387b3f2.svg")
renderPM.drawToFile(drawing, "temp.png", fmt="PNG")


from tkinter import *

tk = Tk()


from PIL import Image, ImageTk

img = Image.open('temp.png')
pimg = ImageTk.PhotoImage(img)
size = img.size


frame = Canvas(tk, width=size[0], height=size[1])
frame.pack()
frame.create_image(0,0,anchor='nw',image=pimg)

tk.mainloop()

like image 58
rizerphe Avatar answered Sep 17 '22 10:09

rizerphe