python - 将 .SVG 图像放入 tkinter Frame

标签 python python-3.x tkinter cairo rsvg

我一直试图把图片来自 https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg进入 Tkinter 框架。我从帖子中找到 here在 rsvg 和 cairo 的帮助下,这是可能的。

我在 Windows 10 上使用 python 3.6。我从 here 得到了 rsvg和开罗来自 here然后将文件夹解压缩到“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\

我不知道现在该做什么

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?



如果我尝试使用 cairo 和 rsvg,因为它们占用的空间很小并且速度非常快;魔杖或其他一些库不是一种选择。我只是希望能够将 SVG 文件放入 tkinter 框架中。如果有人知道如何正确安装 rsvg,我将不胜感激。

任何帮助将不胜感激。
谢谢你的任何建议。

最佳答案

我已经设法使用 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()

关于python - 将 .SVG 图像放入 tkinter Frame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55943631/

相关文章:

python - 使用命令行 waitress-serve 进行日志记录

python - 有没有办法在 Entry() 中存在 int 之前使 OptionMenu() 不可用?

python - 无法创建 tkinter 窗口

转置矩阵的 Python 32/64 位机器浮点求和不正确?

python - Pandas 数据框 : simplest way to find arow and select an element from that row

python - 如何按特定月份/日期过滤日期数据框?

python - 从另一个 postgres 表更新一个 postgres 表

python - django-rest-framework: api 版本控制

python - 如何在Python中将不同的时间序列图合并成二维图

python - Tkinter:使用附加参数对 Button 进行子类化