2010-08-17 28 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庫,因爲所有這些很好的功能都存在,但它們是隱藏的。你必須創建一個新的界面來鏈接到漂亮的功能。