SVG-взаимодействие в Python с Cairo, OpenGL и RSVG - PullRequest
3 голосов
/ 17 августа 2010

Я рендерил огромный SVG-файл с большим количеством элементов с помощью Cairo, OpenGL и rsvg. Я рисую svg на поверхности Каира через rsvg и создаю текстуру OpenGL, чтобы нарисовать ее. Все отлично. И теперь я должен взаимодействовать с элементами из SVG. Например, я хочу угадать элемент по координатам. И я хочу изменить фон какого-то пути в SVG. Я думаю, что в случае смены фона я могу изменить SVG DOM и каким-то образом перерисовать часть SVG. Но в случае элементов проверки попадания я совершенно смущен.

Итак, есть ли библиотека Python для взаимодействия с SVG? Можно ли остаться с cairo и rsvg и как я могу реализовать это сам? Или есть лучший способ визуализации SVG в OpenGL и взаимодействия с ним в Python? Все, что я хочу, это загрузить SVG, манипулировать его DOM и визуализировать его

Ответы [ 4 ]

2 голосов
/ 17 августа 2010

Я не очень разбираюсь в 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
1 голос
/ 17 августа 2010

Альтернативным подходом было бы использование блендер .Он поддерживает импорт SVG и взаимодействие с использованием Python.Я не думаю, что это позволит вам редактировать дом после импорта.

0 голосов
/ 08 июня 2016

Мне пришлось сделать то же самое (например, изменить цвет элемента) и изменить библиотеку rsvg, потому что все эти приятные функции существуют, но они скрыты.Вы должны сделать новый интерфейс для ссылки на приятные функции.

0 голосов
/ 02 ноября 2013

Вы можете использовать самоанализ GObject для взаимодействия с librsvg на Python 3; см. мой ответ на аналогичный вопрос здесь .

...