将.SVG图像放入tkinter Frame

时间:2019-05-01 22:45:57

标签: 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获取cairo,然后将文件夹提取到'C:\ Users ... \ site_packages'文件夹中。他们进口罚款,但我不知道如何使用它们。我尝试使用代码:

def svgPhotoImage(self,file_path_name):
        import Image,ImageTk,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)
mainFrame.configure(image=tk_image)

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\

我不知道现在该怎么办

如果另一个库有效,那就很好;我只希望能够将SVG文件放入tkinter框架中。如果有人知道如何正确安装rsvg和cairo,我将不胜感激。

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

2 个答案:

答案 0 :(得分:2)

我已经成功地使用svglib做到了:

class MyComponent extends React.Component {

  setInterval = () => {
    console.log('Set Interval');
    setTimeout(this.someFunction, 2000);
  }

  someFunction = () => {
    console.log('Some function');
  }

  componentDidMount() {
    this.timer = this.setInterval();
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }
}

答案 1 :(得分:1)

我终于设法在Windows上使用Python 3和PyCairo转换了SVG,但没有rsvg。 Rsvg仍然无法配合,但是显然,没有它,仍然可以加载SVG。

安装过程不是很简单,但是,它可以正常工作!

说明:

请注意,这些说明特定于Windows。在Linux上,只需通过pip安装pycairo并使用PyGObject的rsvg。

  1. https://www.lfd.uci.edu/~gohlke/pythonlibs/下载用于Windows安装的pycairo .whl文件。
  2. 通过pip安装下载的文件:pip install /path/to/your/pycairo/whl.whl如果不起作用,请尝试使用上述链接中的其他文件。可能需要尝试几次。
  3. 运行pip install tinycss cssselect2 defusedxml。这将为下一步安装依赖项。
  4. 转到https://github.com/Kozea/CairoSVG。下载cairosvg文件夹并将其解压缩到您的站点包文件夹,以使您的代码能够导入它。
  5. 转到cairosvg文件夹并打开文件surface.py
  6. 查找显示import cairocffi as cairo的行,并将其替换为import cairo

这足以在没有C ++编译器的Windows上使用PyCairo。幸运的是,这仍然不能解决rsvg问题(相反,它代替了rsvg),但至少可以使用。

以下是一些使用方法的示例:

要将SVG转换为PNG:

import cairosvg
cairosvg.svg2png(url="example.svg", write_to="output.png")

要将SVG放入Tkinter窗口而不下载输出:

import cairosvg
import io
import tkinter as tk
from PIL import Image,ImageTk

main=tk.Tk()

image_data = cairosvg.svg2png(url="example.svg")
image = Image.open(io.BytesIO(image_data))
tk_image = ImageTk.PhotoImage(image)

button=tk.Label(main, image=tk_image)
button.pack(expand=True, fill="both")
main.mainloop()

由于它仍然使用Cairo,因此该解决方案非常快捷,并且几乎没有依赖性。

希望此答案对以后阅读此书的人有用!