3

Cairo、OpenGL、およびrsvgを使用して、多くの要素を含む巨大なSVGファイルをレンダリングします。rsvg 経由で cairo サーフェスに svg を描画し、OpenGL テクスチャを作成して描画します。すべて順調。そして今、SVG の要素を操作する必要があります。たとえば、座標から要素を推測したい。そして、SVG のパスの背景を変更したいと考えています。背景を変更する場合は、SVG DOM を変更して、何らかの形で SVG の一部を再レンダリングできると思います。しかし、ヒット テスト要素の場合、私は完全に恥ずかしい思いをします。

では、SVG と対話するための Python ライブラリはありますか? cairo と rsvg を使い続けることは可能ですか?どうすれば自分で実装できますか? または、SVG を OpenGL でレンダリングし、Python で操作するより良い方法はありますか? 私が望むのは、SVG をロードし、その DOM を操作してレンダリングすることだけです

4

3 に答える 3

2

librsvg についてはよくわかりませんが、2005 年以降更新されていないようです。そのため、別の実装を使用することをお勧めします。

標準ライブラリ以外の Python ライブラリに依存していない場合は、Jython を Batik と一緒に使用できます。これにより、イベント ハンドラーを追加したり、レンダリング後に DOM を変更したりできます。

Java でこれを行う方法の例については、このリンクを参照してください

以下は、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
于 2010-08-17T19:49:11.217 に答える
1

別のアプローチは、blenderを使用することです。svgのインポートとPythonを使用したインタラクションをサポートします。インポート後にdomを編集できるとは思いません。

于 2010-08-17T15:56:28.283 に答える
0

私は同じことをしなければなりませんでした (要素の色を変更するなど)。これらの優れた機能はすべて存在しますが、隠されているため、rsvg ライブラリを変更する必要がありました。便利な機能にリンクするには、新しいインターフェイスを作成する必要があります。

于 2016-06-08T13:26:01.983 に答える