代码之家  ›  专栏  ›  技术社区  ›  Fake Code Monkey Rashid

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

  •  6
  • Fake Code Monkey Rashid  · 技术社区  · 16 年前

    http://david.bellot.free.fr/svg-cards/files/SVG-cards-2.0.1.tar.gz ( 更新: http://svg-cards.sourceforge.net/ )

    你可以抽一张牌 将文件渲染到pixmap上 通过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"));
    

    到目前为止,我的情况是:

    #!/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()
    

    当然,这不管用。

    5 回复  |  直到 15 年前
        1
  •  9
  •   ptomato    16 年前

    rsvg_handle_get_pixbuf_sub() rsvg_handle_render_cairo_sub()

    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= 所以你的程序可以归结为:

    #!/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而不是在角落里的梅花王牌)所以你仍然需要找到一些方法来裁剪你想要的卡片周围的pixbuf,但是这应该不是太难。

        2
  •  2
  •   Adam Crossland    16 年前

    我相信他所说的“通过DOM接口”的意思是,由于SVG是XML,所以可以将SVG文件加载到 ,或其他一些pythonxml解析器,并用您要查找的特定名称提取XML节点。该XML节点应该表示可以呈现的项。

        3
  •  1
  •   QB89Dragon    16 年前

    这是我对裁剪空格问题的答案。这是一个粗糙的过程,但效果很好。这也可以作为一个很好的起点,让任何在python中制作纸牌游戏的人都可以获得纸牌。

    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", {})
    
        4
  •  1
  •   spoorcc    7 年前

    墓穴挖掘在这里有一点,但答案从2010年托马托也工作,现在在2019年的Gtk3与一些轻微的修改。下面的代码将只呈现svg id中的3个方块。

    #!/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()
    
        5
  •  0
  •   Community Mohan Dere    9 年前

    你可以通过编辑标签来完成。编辑宽度和高度,将主svg元素上的viewBox属性设置为所需的矩形,渲染,重复。

    看见 How to show a subsection or "slice" of an SVG graphic? http://dingoskidneys.com/~dholth/svg/