2010-08-17 27 views
3

我使用Cairo,OpenGL和rsvg渲染了大量元素的SVG文件。我通过rsvg在cairo表面上绘制svg并创建一个OpenGL纹理来绘制它。一切安好。现在我必须与SVG中的元素进行交互。例如,我想通过坐标来猜测一个元素。我想改变SVG中某个路径的背景。在我认为改变背景的情况下,我可以改变SVG DOM,并以某种方式重新渲染SVG的一部分。但在命中测试元素的情况下,我完全尴尬。python与开罗,opengl和rsvg的SVG交互

那么,有没有一些Python库与SVG交互?是否可以留在cairo和rsvg中,我怎样才能自己实现它?还是有更好的方法来渲染OpenGL中的SVG并在python中与它进行交互?我想要的只是加载SVG,操作其DOM并渲染它

+0

微软开罗? – 2010-08-17 19:51:36

+0

[常规类](http://en.wikipedia.org/wiki/Cairo_%28graphics%29)我怀疑。 – genpfault 2010-08-17 20:15:14

回答

1

另一种方法是使用blender。它支持使用Python的svg导入和交互。我不认为它会允许你在导入后编辑dom。

2

我对librsvg了解不多,但自2005年以来似乎没有更新过,因此我倾向于推荐使用不同的实现。

如果您没有依赖于标准库之外的任何Python库,那么您可以将Jython与Batik一起使用。这允许您添加事件处理程序,并在渲染后更改DOM。

有关如何使用Java执行此操作的示例,see this link

这里有一个快速端口的Jython 2.2.1(运行,但不是彻底的测试):

from java.awt.event import WindowAdapter; 
from java.awt.event import WindowEvent; 

from javax.swing import JFrame; 

from org.apache.batik.swing import JSVGCanvas; 
from org.apache.batik.swing.svg import SVGLoadEventDispatcherAdapter; 
from org.apache.batik.swing.svg import SVGLoadEventDispatcherEvent; 
from org.apache.batik.script import Window; 

from org.w3c.dom import Document; 
from org.w3c.dom import Element; 
from org.w3c.dom.events import Event; 
from org.w3c.dom.events import EventListener; 
from org.w3c.dom.events import EventTarget; 

class SVGApplication : 

    def __init__(self) : 

     class MySVGLoadEventDispatcherAdapter(SVGLoadEventDispatcherAdapter): 
      def svgLoadEventDispatcherListener(e): 
       # At this time the document is available... 
       self.document = self.canvas.getSVGDocument(); 
       # ...and the window object too. 
       self.window = self.canvas.getUpdateManager().getScriptingEnvironment().createWindow(); 
       # Registers the listeners on the document 
       # just before the SVGLoad event is 
       # dispatched. 
       registerListeners(); 
       # It is time to pack the frame. 
       self.frame.pack(); 

     def windowAdapter(e): 
      # The canvas is ready to load the base document 
      # now, from the AWT thread. 
      self.canvas.setURI("doc.svg"); 

     self.frame = JFrame(windowOpened = windowAdapter, size=(800, 600)); 

     self.canvas = JSVGCanvas(); 
     # Forces the canvas to always be dynamic even if the current 
     # document does not contain scripting or animation. 
     self.canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); 
     self.canvas.addSVGLoadEventDispatcherListener(MySVGLoadEventDispatcherAdapter()) ; 

     self.frame.getContentPane().add(self.canvas); 

     self.frame.show() 

    def registerListeners(self) : 
     # Gets an element from the loaded document. 
     elt = self.document.getElementById("elt-id"); 
     t = elt; 

     def eventHandler(e): 
      print e, type(e) 

      self.window.setTimeout(500,run = lambda : self.window.alert("Delayed Action invoked!")); 
      #window.setInterval(Animation(), 50); 

     # Adds a 'onload' listener 
     t.addEventListener("SVGLoad", false, handleEvent = eventHandler); 

     # Adds a 'onclick' listener 
     t.addEventListener("click", false, handleEvent = eventHandler); 



if __name__ == "__main__": 
    SVGApplication(); 

运行带:

jython -Dpython.path=/usr/share/java/batik-all.jar:/home/jacob/apps/batik-1.7/lib/xml-apis-ext.jar test.py 
0

我不得不做同样的事情(例如改变元素的颜色),并且必须修改rsvg库,因为所有这些很好的功能都存在,但它们是隐藏的。你必须创建一个新的界面来链接到漂亮的功能。