Как визуализировать * части * файла 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/ )

На своем сайте Дэвид говорит:

Вы можете нарисовать карту либо путем рендеринга файла на карту 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() 

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

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

  • Поделиться изображением от mpldatacursor с другими
  • Хотите сделать статический график SVG (из matplotlib) интерактивным через браузер
  • Данные веб-соскабливания с интерактивной диаграммы
  • Изображения SVG не появляются после компиляции пионового кода PyQt4 с py2exe
  • Есть ли скриптовый редактор SVG?
  • Как вставить файл SVG в документ PDF?
  • Создание PDF-файлов из ввода SVG
  • 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 - лучший язык программирования в мире.