Помещение изображений .SVG в рамку tkinter - PullRequest
7 голосов
/ 02 мая 2019

Я пытался поместить изображение из https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg в кадр Tkinter. Из поста здесь я обнаружил, что это возможно с помощью rsvg и cairo.

Я использовал python 3.6 в Windows 10. Я получил rsvg от здесь и cairo от здесь , а затем распаковал папки в C: \ Users ... \ site_packages папка. Они хорошо импортируют, но я не могу понять, как их использовать. Я пытался использовать код:

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)

и

#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)

Попробовав эти сценарии, я продолжал получать сообщение об ошибке:

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

Я уверен, что сделал что-то не так в этом процессе, но после нескольких часов поиска все еще не мог понять, как заставить это работать. Я также попытался установить pycairo (через pip), но получил сообщение об ошибке

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\

Понятия не имею, что делать сейчас

РЕДАКТИРОВАТЬ: я наконец смог получить Пикаиро из https://www.lfd.uci.edu/~gohlke/pythonlibs/ и теперь оно работает. Я наконец получил rsvg, чтобы не дать мне сообщение об ошибке выше, ссылаясь на здесь и получил необходимые файлы DLL от здесь . Каир работает нормально, но RSVG создает пустой экран. Я попробовал другой 7-вкладыш здесь и получить вывод пустого файла вместо преобразованного. Очевидно, что RSVG не работает, и я думаю, что это проблема установки (например, неверные .dll). Помощь

Если я пытаюсь использовать cairo и rsvg, потому что они занимают мало места и действительно быстрые; палочка или какая-то другая библиотека не вариант. Я просто хочу иметь возможность поместить файл SVG в кадр tkinter. Если кто-нибудь знает, как правильно установить rsvg, буду признателен.

Любая помощь будет принята с благодарностью. Спасибо за любые предложения.

...