首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python中的SVG与cairo、opengl和rsvg的交互

python中的SVG与cairo、opengl和rsvg的交互
EN

Stack Overflow用户
提问于 2010-08-17 17:51:04
回答 3查看 3.9K关注 0票数 3

我用Cairo、OpenGL和rsvg渲染了一个包含很多元素的巨大的SVG文件。我通过rsvg在cairo表面绘制svg,并创建一个OpenGL纹理来绘制它。百事大吉。现在我必须与SVG中的元素交互。例如,我想通过坐标来猜测一个元素。我想在SVG中更改一些路径的背景。在改变背景的情况下,我想我可以改变SVG DOM并以某种方式重新呈现SVG的一部分。但在命中测试元素的情况下,我感到非常尴尬。

那么,有没有一些python库可以与SVG交互呢?我可以继续使用cairo和rsvg吗?我如何自己实现它?或者有没有更好的方法在OpenGL中呈现SVG并在python中与其交互?我想要的就是加载SVG,操作它的DOM并渲染它

EN

回答 3

Stack Overflow用户

发布于 2010-08-18 03:49:11

我对librsvg了解不多,但它似乎自2005年以来就没有更新过,所以我倾向于建议使用不同的实现。

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

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

以下是到Jython 2.2.1的快速移植(运行,但未经过全面测试):

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

运行时使用:

代码语言:javascript
复制
jython -Dpython.path=/usr/share/java/batik-all.jar:/home/jacob/apps/batik-1.7/lib/xml-apis-ext.jar test.py
票数 2
EN

Stack Overflow用户

发布于 2010-08-17 23:56:28

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

票数 1
EN

Stack Overflow用户

发布于 2016-06-08 21:26:02

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

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

https://stackoverflow.com/questions/3501215

复制
相关文章

相似问题

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