Как визуализировать * части * файла svg?

Я хочу отображать части файла svg по имени, но для жизни меня не могу понять, как это сделать (используя python + gtk).

Вот файл svg, о котором идет речь: http://david.bellot.free.fr/svg-cards/files/SVG-cards-2.0.1.tar.gz ( Обновление: этот файл больше не существует, но вы можете отслеживать его вниз по адресу http://svg-cards.sourceforge.net/ )

  • Преобразование SVG в PNG в Python
  • Как получить прозрачный фон в окне с PyGTK и PyCairo?
  • Как выполнить тестирование функции Python, которая рисует графику PDF?
  • Ошибка с типами python и librsvg
  • Сохраните содержимое шаблона Gtk.DrawingArea или Cairo для изображения на диске
  • На своем сайте Дэвид говорит:

    Вы можете нарисовать карту либо путем рендеринга файла на карту pixmap, либо отсечения каждой карты вручную, либо с помощью имени карты через интерфейс DOM. Все карты встроены в группу SVG.

    Я не знаю, что он подразумевает под интерфейсом DOM. Я сделал некоторые поиски и лучший результат, который я нашел, который, похоже, соответствует тому, что я хочу сделать:

    QSvgRenderer *renderer = new QSvgRenderer(QLatin1String("SvgCardDeck.svg")); QGraphicsSvgItem *black = new QGraphicsSvgItem(); QGraphicsSvgItem *red = new QGraphicsSvgItem(); black->setSharedRenderer(renderer); black->setElementId(QLatin1String("black_joker")); red->setSharedRenderer(renderer); red->setElementId(QLatin1String("red_joker")); 

    Обратите внимание, однако, что это для Qt и даже не написано на python.

    Это то, что у меня есть до сих пор:

     #!/usr/bin/env python from __future__ import absolute_import import cairo import gtk import rsvg from xml import xpath from xml.dom import minidom window = gtk.Window() window.set_title("Foo") window.set_size_request(256, 256) window.set_property("resizable", False) window.set_position(gtk.WIN_POS_CENTER) window.connect("destroy", gtk.main_quit) window.show() document = minidom.parse("cards.svg") element = xpath.Evaluate("//*[@id='1_club']", document)[0] xml = element.toxml() svg = rsvg.Handle() svg.write(xml) pixbuf = svg.get_pixbuf() image = gtk.Image() image.set_from_pixbuf(pixbuf) image.show() window.add(image) gtk.main() 

    Конечно, это не сработает.

    Что мне не хватает?

  • Вставить evince Python GI
  • Индикатор выполнения не обновляется во время работы
  • Преобразование скрипта python GTK в C
  • Как получить список всех окон на рабочем столе gnome2 с помощью pygtk?
  • Расширение от GtkBin
  • Преобразование SVG в PNG в Python
  • 4 Solutions collect form web for “Как визуализировать * части * файла svg?”

    Библиотека GTK для рендеринга SVG называется RSVG. У него есть привязки python, но они недокументированы, и они не обертывают функции rsvg_handle_get_pixbuf_sub() и rsvg_handle_render_cairo_sub() которые вы обычно использовали для этой цели в C. Вот что вы должны делать, насколько я могу судить. Вы извлекаете узел XML, как предложил Адам Кроссленд. Чтобы сделать это, вы должны сделать что-то вроде этого:

     import gtk import rsvg handle = rsvg.Handle() handle.write(buffer=xml_data) # xml_data is the XML string for the object you want image = gtk.Image() image.set_from_pixbuf(handle.get_pixbuf()) 

    Это если вы хотите его в gtk.Image , иначе сделайте что-нибудь еще с pixbuf. Вы также можете отобразить его в контексте Каира с помощью handle.render_cairo(cr) где cr – ваш каирский контекст.

    РЕДАКТИРОВАТЬ:

    Извините, я не очень хорошо читал привязки python. Функции _sub() реализуются с использованием аргумента id= , поэтому ваша программа может сводиться к следующему:

     #!/usr/bin/env python import gtk import rsvg window = gtk.Window() window.set_title("Foo") window.connect("destroy", gtk.main_quit) window.show() svg = rsvg.Handle(file='cards.svg') pixbuf = svg.get_pixbuf(id='#3_diamond') image = gtk.Image() image.set_from_pixbuf(pixbuf) image.show() window.add(image) gtk.main() 

    Я тестировал это, и он работает. Тем не менее, окно представляет собой размер всего холста SVG и обрезается до размера экрана (именно поэтому я отобрал 3 бриллианта вместо туза клубов, которая находится в углу.) Таким образом, вы все равно будете иметь чтобы найти способ обрезать pixbuf вокруг карты, которую вы хотите, но это не должно быть слишком сложно.

    Я считаю, что его «через интерфейс DOM» означает, что, поскольку SVG является XML, вы можете загрузить файл SVG в мини-миниме или какой-нибудь другой парсер XML Python и извлечь узел XML с определенным именем, которое вы ищете , Этот узел XML должен представлять объект, который может быть отображен.

    Вот мой ответ на проблему с пустым пространством обрезки. Это грубый взлом, но он отлично поработал. Это также послужит хорошей отправной точкой для получения карт для тех, кто делает карточную игру на питоне.

     import gtk import rsvg svg = rsvg.Handle(file="/usr/share/gnome-games-common/cards/gnomangelo_bitmap.svg") w, h = 202.5, 315 card_names = map(str, range(1,11)) + ["jack", "queen", "king"] suites = ["club", "diamond", "heart", "spade"] specials = [{"name":"black_joker","x":0, "y":4}, {"name":"red_joker","x":1, "y":4}, {"name":"back","x":2, "y":4}] for suite_number, suite in enumerate(suites): for card_number, card in enumerate(card_names): print "processing", suite, card, '#'+card+'_'+suite pixbuf = svg.get_pixbuf(id='#'+card+'_'+suite) pixbuf.subpixbuf(int(w*card_number), int(h*suite_number), int(w), int(h)).save("./"+card+"_"+suite+".png","png", {}) for special in specials: print "processing", special["name"] pixbuf = svg.get_pixbuf(id='#'+special["name"]) card_number = special["x"] suite_number = special["y"] pixbuf.subpixbuf(int(w*card_number), int(h*suite_number), int(w), int(h)).save("./"+special["name"]+".png","png", {}) 

    Вы можете сделать это, отредактировав тег. Измените ширину и высоту, установите атрибут viewBox в главном элементе svg на прямоугольник, который вы хотите, выполните рендеринг, повторите.

    См. Как показать подраздел или «срез» графического объекта SVG? и http://dingoskidneys.com/~dholth/svg/

    Python - лучший язык программирования в мире.