我想按名称渲染 svg 文件的一部分,但我一生都不知道如何做到这一点(使用 python + gtk)。
这是有问题的 svg 文件:http://david.bellot.free.fr/svg-cards/files/SVG-cards-2.0.1.tar.gz (Update:该文件不再存在,但您可以在以下位置找到它http://svg-cards.sourceforge.net/)
大卫在他的网站上说:
您可以通过以下方式抽一张牌:
将文件渲染到像素图上并
手动或通过剪裁每张卡片
通过 DOM 使用卡的名称
界面。所有卡片均嵌入
SVG 组。
我不知道他所说的 DOM 接口是什么意思。我做了一些搜索,我发现似乎符合我想做的最好结果是:
QSvgRenderer *renderer = new QSvgRenderer(QLatin1String("SvgCardDeck.svg"));
QGraphicsSvgItem *black = new QGraphicsSvgItem();
QGraphicsSvgItem *red = new QGraphicsSvgItem();
black->setSharedRenderer(renderer);
black->setElementId(QLatin1String("black_joker"));
red->setSharedRenderer(renderer);
red->setElementId(QLatin1String("red_joker"));
但请注意,它是针对 Qt 的,甚至不是用 python 编写的。
这是我到目前为止所拥有的:
#!/usr/bin/env python
from __future__ import absolute_import
import cairo
import gtk
import rsvg
from xml import xpath
from xml.dom import minidom
window = gtk.Window()
window.set_title("Foo")
window.set_size_request(256, 256)
window.set_property("resizable", False)
window.set_position(gtk.WIN_POS_CENTER)
window.connect("destroy", gtk.main_quit)
window.show()
document = minidom.parse("cards.svg")
element = xpath.Evaluate("//*[@id='1_club']", document)[0]
xml = element.toxml()
svg = rsvg.Handle()
svg.write(xml)
pixbuf = svg.get_pixbuf()
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
image.show()
window.add(image)
gtk.main()
当然,这是行不通的。
我缺少什么?
用于渲染 SVG 的 GTK 库称为 RSVG。它有 python 绑定,但它们没有文档记录,并且它们不包装rsvg_handle_get_pixbuf_sub()
and rsvg_handle_render_cairo_sub()
您通常在 C 中为此目的使用的函数。据我所知,这就是您必须执行的操作。您按照 Adam Crossland 的建议提取 XML 节点。要渲染它,您必须执行以下操作:
import gtk
import rsvg
handle = rsvg.Handle()
handle.write(buffer=xml_data)
# xml_data is the XML string for the object you want
image = gtk.Image()
image.set_from_pixbuf(handle.get_pixbuf())
如果你想要它在一个gtk.Image
,否则对 pixbuf 执行其他操作。您还可以将其渲染到开罗上下文handle.render_cairo(cr)
where cr
是您的开罗背景。
EDIT:
抱歉,我一开始没有仔细阅读 python 绑定。这_sub()
功能是使用实现的id=
参数,所以你的程序可以归结为:
#!/usr/bin/env python
import gtk
import rsvg
window = gtk.Window()
window.set_title("Foo")
window.connect("destroy", gtk.main_quit)
window.show()
svg = rsvg.Handle(file='cards.svg')
pixbuf = svg.get_pixbuf(id='#3_diamond')
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
image.show()
window.add(image)
gtk.main()
我测试了这个并且它有效。然而,窗口的大小是整个 SVG 画布的大小,并且被裁剪为屏幕大小(这就是为什么我渲染方块 3 而不是角落里的梅花 A 的原因。)所以你仍然会得到找到一些方法来裁剪你想要的卡周围的 pixbuf,但这应该不会太难。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)