Hi all,

Information on using tkinter for displaying an svg image seems a bit low spread on the Internet. I recently played around with pygame and svg and realized, hold on this can be done with tk too. So I thought I post a little example for future generations :-) (and also have stored at http://dcuktec.googlecode.com/hg/source/examples/cairo_rsvg_tkinter.py).

So here it is if you are interested:

---
#! /usr/bin/env python
"""
Tkinter example for displaying SVG in a PhotoImage class using cairo and rsvg. Note that this is relatively slow, this is mainly due to converting the cairo
surface data to the appropriate rgb values and putting each pixel in the
PhotoImage class.
"""
import cairo
import rsvg
# I had a bit of trouble finding the rsvg python wrapper, turns out it is part # of the GnomePythonDesktop package, windows users are even less supported see: # http://cairographics.org/cairo_rsvg_and_python_in_windows/ to get it working.
import Tkinter

def _alpha_blending(rgba, back):
    "Return a rgb tuple composed from a rgba and back(ground) tuple/list."
    paired = zip(rgba[:-1], back)
    alpha = rgba[-1]
    tmp = list()
    for upper, lower in paired:
        blend = (((255 - alpha) * lower) + (alpha * upper)) / 255
        tmp.append(blend)

    return(tuple(tmp))

def convert(bgra_buffer, width, height):
    "Convert bgra buffer to photoimage put"
    idx = 0
    end = len(bgra_buffer)
    arguments = list()

    while idx < end:
        rgba = (ord(bgra_buffer[idx + 2]),
                ord(bgra_buffer[idx + 1]),
                ord(bgra_buffer[idx + 0]),
                ord(bgra_buffer[idx + 3]))
        back = (255, 255, 255)
        rgb = _alpha_blending(rgba, back)
        arguments += rgb
        idx += 4

template = ' '.join(height *['{%s}' % (' '.join(width*["#%02x%02x%02x"]))])
    return(template % tuple(arguments))


def photoimage_from_svg(file_path_name):
"Return a Tkinter.PhotoImage with the content set to the rendered SVG."
    svg = rsvg.Handle(file=file_path_name)
    width, height = svg.get_dimension_data()[:2]
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, int(width), int(height))
    context = cairo.Context(surface)
    svg.render_cairo(context)
    image = Tkinter.PhotoImage(width=width, height=height)
    data = convert(surface.get_data(), width, height)
    image.put(data)
    return(image)

if __name__ == '__main__':
    SVG = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
       xmlns:svg="http://www.w3.org/2000/svg";
       xmlns="http://www.w3.org/2000/svg";
       id="test" version="1.1" width="900" height="600">
       <rect id="red"    width="300" height="300" x="000" y="000"
              style="fill:#ff0000;fill-opacity:1.0;stroke:none" />
       <rect id="green"  width="300" height="300" x="300" y="000"
              style="fill:#00ff00;fill-opacity:1.0;stroke:none" />
       <rect id="blue"   width="300" height="300" x="600" y="000"
              style="fill:#0000ff;fill-opacity:1.0;stroke:none" />
       <rect id="black"  width="300" height="300" x="000" y="300"
               style="fill:#000000;fill-opacity:1.0;stroke:none" />
       <rect id="grey"  width="300" height="300" x="300" y="300"
               style="fill:#000000;fill-opacity:0.5;stroke:none" />
       <rect id="white" width="300" height="300" x="600" y="300"
              style="fill:#ffffff;fill-opacity:1.0;stroke:none" />
    </svg>"""
    import os, tempfile
    #
    PATH = tempfile.mkstemp()[1]
    OPEN = open(PATH, 'w')
    OPEN.writelines(SVG)
    OPEN.close()
    ROOT = Tkinter.Tk()
    #
    IMAGE = photoimage_from_svg(PATH)
    #
    os.remove(PATH)
    BUTTON = Tkinter.Button(ROOT, image=IMAGE)
    BUTTON._photoimage = IMAGE
    BUTTON.grid()
    Tkinter.mainloop()
---
--
mph
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to