首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何呈现svg文件的*部件?

如何呈现svg文件的*部件?
EN

Stack Overflow用户
提问于 2010-02-23 19:44:54
回答 5查看 6.7K关注 0票数 6

我想按名称呈现svg文件的各个部分,但对于我的生活,我不知道如何这样做(使用python + gtk)。

下面是有问题的svg文件:http://david.bellot.free.fr/svg-cards/files/SVG-cards-2.0.1.tar.gz (更新:这个文件已经不存在了,但是您可以在http://svg-cards.sourceforge.net/跟踪它)

在他的网站上,大卫说:

,您可以通过将文件呈现到像素地图上并手动裁剪每张卡,或者通过DOM接口使用卡片的名称来绘制卡片。所有卡都嵌入到SVG组中。

我不知道他所说的DOM接口是什么意思。我已经做了一些搜索,我发现最好的结果似乎符合我想做的是:

代码语言:javascript
复制
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编写的。

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
#!/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()

当然不管用。

我遗漏了什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-23 21:34:57

用于呈现SVG的GTK库称为RSVG。它有python绑定,但是它们是没有文档的,而且它们没有包装您通常在C中使用的rsvg_handle_get_pixbuf_sub()rsvg_handle_render_cairo_sub()函数。按照的建议,提取XML节点。要渲染它,您必须这样做:

代码语言:javascript
复制
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,否则做其他事情与像素。您还可以使用handle.render_cairo(cr)将其呈现给开罗上下文,其中cr是您的开罗上下文。

编辑:

对不起,一开始我没有仔细阅读python绑定。_sub()函数是使用id=参数实现的,因此您的程序可以归结为:

代码语言:javascript
复制
#!/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颗钻石,而不是角落里的球杆王牌)。因此,您仍然需要找到一些方法来裁剪您想要的卡周围的像素,但这应该不会太难。

票数 9
EN

Stack Overflow用户

发布于 2010-05-26 03:48:58

这是我对裁剪空白问题的答案。这是一次粗暴的攻击,但效果很好。这也是一个很好的起点,为任何人在python中制作纸牌游戏提供了一个良好的起点。

代码语言:javascript
复制
import gtk
import rsvg
svg = rsvg.Handle(file="/usr/share/gnome-games-common/cards/gnomangelo_bitmap.svg")
w, h = 202.5, 315
card_names = map(str, range(1,11)) + ["jack", "queen", "king"]
suites = ["club", "diamond", "heart", "spade"]
specials = [{"name":"black_joker","x":0, "y":4}, {"name":"red_joker","x":1, "y":4}, {"name":"back","x":2, "y":4}]
for suite_number, suite in enumerate(suites):
    for card_number, card in enumerate(card_names):
        print "processing", suite, card, '#'+card+'_'+suite
        pixbuf = svg.get_pixbuf(id='#'+card+'_'+suite)
        pixbuf.subpixbuf(int(w*card_number), int(h*suite_number), int(w), int(h)).save("./"+card+"_"+suite+".png","png", {})
for special in specials:
    print "processing", special["name"]
    pixbuf = svg.get_pixbuf(id='#'+special["name"])
    card_number = special["x"]
    suite_number = special["y"]
    pixbuf.subpixbuf(int(w*card_number), int(h*suite_number), int(w), int(h)).save("./"+special["name"]+".png","png", {})
票数 2
EN

Stack Overflow用户

发布于 2019-01-17 21:32:04

在这里挖一些坟墓,但2010年的答案也适用于Gtk3,但也有一些轻微的修改。下面的代码将只呈现3颗钻石svg id。

代码语言:javascript
复制
#!/usr/bin/env python

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Rsvg', '2.0')

from gi.repository import Gtk, Rsvg

svg = Rsvg.Handle.new_from_file('svg-cards.svg')

pixbuf = svg.get_pixbuf_sub('#3_diamond')

image = Gtk.Image()
image.set_from_pixbuf(pixbuf)
image.show()

window = Gtk.Window()
window.set_title("Foo")
window.connect("destroy", Gtk.main_quit)
window.show()
window.add(image)

Gtk.main()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2321155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档