将 .SVG 图像放入 tkinter Frame
Putting .SVG images into tkinter Frame
我一直在尝试将来自 https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg into a Tkinter frame. I found from the post here 的图像放在 rsvg 和 cairo 的帮助下是可能的。
我在 Windows 10 上使用 python 3.6。我从 here and cairo from here 获取了 rsvg,然后将文件夹提取到 '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,因为它们占用很少 space 并且速度非常快;魔杖或其他一些图书馆不是一个选择。我只想将 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 3 和 Windows 上的 PyCairo 转换 SVG,但没有 rsvg。 Rsvg 仍然不合作,但显然没有它仍然可以加载 SVG。
安装过程不是很简单,但是,嘿,它有效!
说明:
请注意,这些说明是 Windows 特定的。在 Linux,可以简单地通过 pip 安装 pycairo 并使用 PyGObject 的 rsvg。
- 从 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载用于 Windows 安装的 pycairo .whl 文件。
- 通过 pip 安装下载的文件:
pip install /path/to/your/pycairo/whl.whl
如果这不起作用,请尝试使用与上述文件不同的文件 link。可能需要尝试几次。
- 运行
pip install tinycss cssselect2 defusedxml
。这将为下一步安装依赖项。
- 前往 https://github.com/Kozea/CairoSVG。下载
cairosvg
文件夹并将其解压缩到您的站点包文件夹,使您的代码能够导入它。
- 转到
cairosvg
文件夹并打开文件 surface.py
。
- 查找显示
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 window:
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,因此这个解决方案非常快,并且几乎没有依赖项。
希望这个回答对以后阅读本文的人有用!
这是另一种方法:
from pylunasvg import Document
import numpy as np
from urllib import request
from PIL import Image
contents = request.urlopen("https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg").read()
document = Document.loadFromData(contents)
bitmap = document.renderToBitmap()
svgArray = np.array(bitmap, copy=False)
img = Image.fromarray(svgArray)
# Insert tkinter code here
免责声明:我为库编写了绑定,这里是 github link:pylunasvg and link to the original library written in c++: lunasvg
我一直在尝试将来自 https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg into a Tkinter frame. I found from the post here 的图像放在 rsvg 和 cairo 的帮助下是可能的。
我在 Windows 10 上使用 python 3.6。我从 here and cairo from here 获取了 rsvg,然后将文件夹提取到 '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,因为它们占用很少 space 并且速度非常快;魔杖或其他一些图书馆不是一个选择。我只想将 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 3 和 Windows 上的 PyCairo 转换 SVG,但没有 rsvg。 Rsvg 仍然不合作,但显然没有它仍然可以加载 SVG。
安装过程不是很简单,但是,嘿,它有效!
说明:
请注意,这些说明是 Windows 特定的。在 Linux,可以简单地通过 pip 安装 pycairo 并使用 PyGObject 的 rsvg。
- 从 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载用于 Windows 安装的 pycairo .whl 文件。
- 通过 pip 安装下载的文件:
pip install /path/to/your/pycairo/whl.whl
如果这不起作用,请尝试使用与上述文件不同的文件 link。可能需要尝试几次。 - 运行
pip install tinycss cssselect2 defusedxml
。这将为下一步安装依赖项。 - 前往 https://github.com/Kozea/CairoSVG。下载
cairosvg
文件夹并将其解压缩到您的站点包文件夹,使您的代码能够导入它。 - 转到
cairosvg
文件夹并打开文件surface.py
。 - 查找显示
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 window:
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,因此这个解决方案非常快,并且几乎没有依赖项。
希望这个回答对以后阅读本文的人有用!
这是另一种方法:
from pylunasvg import Document
import numpy as np
from urllib import request
from PIL import Image
contents = request.urlopen("https://betacssjs.chesscomfiles.com/bundles/web/favicons/safari-pinned-tab.f387b3f2.svg").read()
document = Document.loadFromData(contents)
bitmap = document.renderToBitmap()
svgArray = np.array(bitmap, copy=False)
img = Image.fromarray(svgArray)
# Insert tkinter code here
免责声明:我为库编写了绑定,这里是 github link:pylunasvg and link to the original library written in c++: lunasvg