[英]How to open SVG files in tkinter?
I want to be able to open SVG files in tkinter. The answer I'm using right now converts the SVG into a PNG before showing it in tkinter, but since I want to be to resize it without losing quality, I need a better answer.我希望能够在 tkinter 中打开 SVG 个文件。我现在使用的答案是将 SVG 转换为 PNG,然后在 tkinter 中显示它,但由于我想在不损失质量的情况下调整它的大小,我需要一个更好的答案.
Some basic svg support will be part of tk 8.7 ( https://core.tcl-lang.org/tips/doc/trunk/tip/507.md ).一些基本的 svg 支持将成为 tk 8.7 ( https://core.tcl-lang.org/tips/doc/trunk/tip/507.md ) 的一部分。
But to add svg support to tk 8.6, it is necessary to install an extra package like tksvg .但是要为 tk 8.6 添加 svg 支持,需要安装额外的 package ,如tksvg 。 So, first install tksvg, following the instructions from here .
因此,首先按照此处的说明安装 tksvg。 Then you can create a
PhotoImage
from a svg file but you need to load tksvg in the tcl interpreter.然后您可以从 svg 文件创建一个
PhotoImage
,但您需要在 tcl 解释器中加载 tksvg。 I wrote a quick python wrapper for tksvg:我为 tksvg 写了一个快速的 python 包装器:
import tkinter as tk
class SvgImage(tk.PhotoImage):
"""Widget which can display images in PGM, PPM, GIF, PNG format."""
_tksvg_loaded = False
_svg_options = ['scale', 'scaletowidth', 'scaletoheight']
def __init__(self, name=None, cnf={}, master=None, **kw):
# load tksvg
if not SvgImage._tksvg_loaded:
if master is None:
master = tk._default_root
if not master:
raise RuntimeError('Too early to create image')
master.tk.eval('package require tksvg')
SvgImage._tksvg_loaded = True
# remove specific svg options from keywords
svgkw = {opt: kw.pop(opt, None) for opt in self._svg_options}
tk.PhotoImage.__init__(self, name, cnf, master, **kw)
# pass svg options
self.configure(**svgkw)
def configure(self, **kw):
svgkw = {opt: kw.pop(opt) for opt in self._svg_options if opt in kw}
# non svg options
if kw:
tk.PhotoImage.configure(self, **kw)
# svg options
options = ()
for k, v in svgkw.items():
if v is not None:
options = options + ('-'+k, str(v))
self.tk.eval('%s configure -format {svg %s}' % (self.name, ' '.join(options)))
So SvgImage
is like a PhotoImage
but it has the additional options (only one of them can be specified since they are three different way of specifying the image size):所以
SvgImage
就像PhotoImage
但它有额外的选项(只能指定其中一个,因为它们是指定图像大小的三种不同方式):
scale
scaletowidth
: width in pixel scaletowidth
:以像素为单位的宽度scaletoheight
: height in pixel scaletoheight
: 以像素为单位的高度Here is an example:这是一个例子:
root = tk.Tk()
def rescale():
global scale
scale += 0.5
img.configure(scale=scale)
scale = 0.5
img = SvgImage(master=root, file='/path/to/file.svg', scale=scale)
tk.Button(root, image=img, command=rescale).pack()
root.mainloop()
I think that there is no way of doing this without losing quality resolutions, but if svglib was not good enough maybe cairo can do it better.我认为没有办法在不损失质量分辨率的情况下做到这一点,但如果 svglib 不够好,也许 cairo 可以做得更好。 Try the code bellow.
试试下面的代码。 It has the advantage that you don't really need the image as a png file, but since PIL does not handle svg you have to convert it anyway:
它的优点是您实际上并不需要将图像作为 png 文件,但由于 PIL 不处理 svg 无论如何您都必须转换它:
from io import BytesIO
import cairosvg
from PIL import Image
out = BytesIO()
cairosvg.svg2png(url='path/to/svg', write_to=out)
image = Image.open(out)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.