Mit Daten aus Inkscape Dateien rechnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Vipr0
User
Beiträge: 4
Registriert: Dienstag 14. März 2017, 21:19

Hallo,
ich möchte in Python Berechnungen mit Daten aus Inkscape Dateien (Inkscape SVG oder normaler SVG) durchführen. Leider fehlen mir die Kentnisse, wie ich an diese Daten (Objektarten, deren Koordinaten und ähnliches) am besten herankomme. Es scheint Parser zu geben und auch Inkscape Erweiterungen, welche ich nicht verstehe. Hat jemand eventuell Erfahrung auf diesem Gebiet und kann mir weiter helfen, wie ich an mein Problem herrangehe? Gibt es Vorschläge für spezielle Parser, die für mich funktionieren, oder sollte ich versuchen selber etwas ähnliches zu schreiben? Gesucht sind vor allem die Objektarten, deren Koordinaten, ob diese bestimmte Farben haben, der Inhalt von eventuellen Textfeldern und eventuell auch Knotenmarkierungen.
Danke im vorraus.

VG Vipr0
BlackJack

@Vipr0: Das ist alles ein bisschen sehr allgemein beschrieben. So ganz allgemein geantwortet würde ich mich an Deiner Stelle mit dem SVG-Format auseinandersetzen, damit Du bestehende Parser besser beurteilen kannst, bevor Du Dir etwas eigenes programmierst. Ein reiner XML-Parser reicht bei SVG nicht, weil nicht alle Daten als XML kodiert sind. Pfade zum Beispiel sind Attributwerte mit einer eigenen Syntax. Ist natürlich auf der einen Seite doof, auf der anderen Seite wäre das alles in XML ausgedrückt viel grösser.
Vipr0
User
Beiträge: 4
Registriert: Dienstag 14. März 2017, 21:19

Danke für die Antwort!
Okay ich versuche mich genauer auszudrücken. Ich will die Koordinaten von eventuell vorhandenen path-Objekten, dessen Farbe und Knotenmarkierungen, sowie die Koordinaten und Füllfarbe von rectangle-Objekten, als auch den Inhalt von Textfeldern in in irgendeiner Form auslesen. Ich weiß nicht wie sowas normalerweise realisiert wird aber ich habe mir beispielsweise vorgestellt, dass ich eine Liste mit abwechselnd X und Y Koordinaten bekomme, oder eine Liste mit komplexen Zahlen, wobei der Realteil die X Koordinaten und der Imaginärteil die Y-Koordinaten sind. Außerdem könnte das erste Element der Liste die Objektart angeben und das zweite die Farbe oder so ähnlich. Leider weiß ich nicht wie ich an die Sache herrangehen soll. Sollte ich beispielsweise versuchen den code von etwas wie dem sv.path 2.2 zu verstehen?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Vipr0: Du solltest vielleicht nicht gleich versuchen, den Code eines Moduls zu verstehen, sondern Dir die Dokumentation dazu durchlesen und schauen, ob das Modul Dein Problem löst oder nicht.
Vipr0
User
Beiträge: 4
Registriert: Dienstag 14. März 2017, 21:19

Vielen Dank.
Ich konnte die Dateien auslesen und bin dabei leider auf ein anderes Problem gestoßen.
Ich erhalte eine liste, welche in diesem Beispiel zwei Listen enthält und wie folgt aussieht:
[['m', '-407.45833,31.660713', '55.94048,-96.761902', '136.07143,106.589284', 'z'], ['m', '-136.82738,39.976189', '35.52976,-120.196426', '43.089287,124.732141']]
Wie ihr seht sind die x und y Koordinaten zusammen (durch ein Komma getrennt) in den Elementen der Unterlisten vorhanden.
Ich hätte aber gerne Unterlisten in denen jeder Koordinatenteil ein Element besitzt, die also wie folgt aussieht:
[['m', '-407.45833', '31.660713', '55.94048', '-96.761902', '136.07143', '106.589284', 'z'], ['m', '-136.82738', '39.976189', '35.52976', '-120.196426', '43.089287', '124.732141']]

Ich habe es mit folgendem Code probiert:

Code: Alles auswählen

	liste2=[]
	for j in range(0, len(liste)):
		for i in range(0, len(liste[j])):
			liste2.append(liste[j][i].split(',',1))
	print(liste2)
Allerdings liefert er nur die liste2 mit:
[['m'], ['-407.45833', '31.660713'], ['55.94048', '-96.761902'], ['136.07143', '106.589284'], ['z'], ['m'], ['-136.82738', '39.976189'], ['35.52976', '-120.196426'], ['43.089287', '124.732141']]

Kann mir jemand helfen?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Vipr0: wie bist Du denn jetzt an diese Listen gekommen? Du hättest wahrscheinlich lieber so Listen, wie Du hast, als solche die Du wünschst. Was willst Du eigentlich damit machen? So trivial ist SVG-Dateien interpretieren nicht.
Vipr0
User
Beiträge: 4
Registriert: Dienstag 14. März 2017, 21:19

Auslesen der Dateien:

Code: Alles auswählen

	from xml.dom import minidom
	src = r'C:\Users\bla\test.svg'
	doc = minidom.parse(src)
	global path_d	
	path_d = [path.getAttribute('d') for path
					in doc.getElementsByTagName('path')]
Ergebnis von path_d:
['m -407.45833,31.660713 55.94048,-96.761902 136.07143,106.589284 z', 'm -136.82738,39.976189 35.52976,-120.196426 43.089287,124.732141']

Liste generieren

Code: Alles auswählen

	for i in range(0, len(path_d)):
		liste.append(path_d[i].split())
Ergebnis von liste:
[['m', '-407.45833,31.660713', '55.94048,-96.761902', '136.07143,106.589284', 'z'], ['m', '-136.82738,39.976189', '35.52976,-120.196426', '43.089287,124.732141']]

Cod vom letzten Beitrag liefert liste2:
[['m'], ['-407.45833', '31.660713'], ['55.94048', '-96.761902'], ['136.07143', '106.589284'], ['z'], ['m'], ['-136.82738', '39.976189'], ['35.52976', '-120.196426'], ['43.089287', '124.732141']]

Ich will mit den Koordinaten Berechnungen durchführen, je nach dem was für eine Farbe der Path zum Beispiel hat und diese dann in bestimmter Form in Textdateien einfügen.
Mit dem Ergebnis von liste2 könnte ich schon arbeiten aber zumindest eine Unterteilung wäre toll, so dass nicht die Koordinaten von allen paths innerhalb einer Liste vorkommen, ohne auf irgendeine Weise getrennt zu sein. Die einzige Möglichkeit im jetzigen Zustand, die paths auseinander zu halten ist, dass der neue wieder mit ['z'] anfängt.


Daher wäre es mir lieber wenn ich die Liste bearbeite, sodass sie so aussieht:
[['m', '-407.45833', '31.660713', '55.94048', '-96.761902', '136.07143', '106.589284', 'z'], ['m', '-136.82738', '39.976189', '35.52976', '-120.196426', '43.089287', '124.732141']]

oder so:
[[['m'], ['-407.45833', '31.660713'], ['55.94048', '-96.761902'], ['136.07143', '106.589284']], [['z'], ['m'], ['-136.82738', '39.976189'], ['35.52976', '-120.196426'], ['43.089287', '124.732141']]]
BlackJack

@Vipr0: Du gehst das parsen zu simpel an, denn die müssen ja nicht genau *so* aussehen. Bei den Kommas zwischen den Koordinaten dürfen auch Leerzeichen vorkommen, dann funktioniert das mit dem `split()` nicht mehr so und die Koordinaten können auch anders, ohne die Kommas angegeben werden. Auf der anderen Seite muss zwischen Pfad-Befehl und erster Koordinate *kein* Leerzeichen stehen. Selbst zwischen zwei Zahlen muss kein Leerzeichen sein wenn die zweite Zahl negativ ist, weil dann das Vorzeichen die erste Zahl beendet.

Du hast doch bereits einen Parser gefunden, warum verwendest Du den nicht?
Antworten