[python-users] canvas export nach svg
Thomas Lenarz
tommesml at netcologne.de
Do Jun 25 19:13:31 CEST 2009
Andreas schrieb:
> Ich brauch zwar nur einen abgeänderten Teil deiner Zeichenoberfläche,
> erweitert um die 'export_as_svg' methode (korrekt angeschlossen), jedoch
> speichert es mir die Farbinformationen der Canvasobjekte nicht mit ab
> (den Rest schon). Hab die Lösung leider bisher nicht finden können, da
> ich mich mit dem svg Format kaum auskenne.
Hallo Andi,
vielen Dank erst einmal für Deine Anfrage. Es ist schön zu wissen, dass
sich noch jemand anders mit den gleichen Dingen beschäftigt :-)
Farben (außer schwarz) habe ich ja bisher mehr oder weniger konsequent
ignoriert. Es ist tatsächlich aber recht einfach.
Die Canvas-Objekte kennen (je nach Objekttyp etwas unterschiedlich) die
beiden Optionen fill und outline. SVG hingegen kennt fill und stroke
(siehe auch: http://www.w3.org/TR/SVG11/shapes.html#RectElement). Ich
habe jedoch den Eindruck, dass fill aus TK-Canvas-Sicht nicht immer auch
zwangsläufig fill aus SVG-Sicht bedeutet. Je nach Objekttyp wird man
outline auf stroke oder fill auf stroke abbilden müssen.
Ich habe das Ganze einmal wie folgt im Graphrenderer ausprobiert:
Ich habe alle Linien des Graphen einmal versuchsweise blau gezeichnet
und dann beim Erzeugen der Objekt-Enumeration aus dem Canvas jeweils die
Option fill mit ausgelesen (mit itemcget() ).
Beim Erzeugen des SVG Outputs habe ich dann diesen Wert direkt in das
neu erzeugte Attribut "stroke" zur polyline hinzugefügt.
Wenn man sich das SVG danach anschaut, sind tatsächlich auch hier alle
Linien blau.
Das ist natürlich zunächst einmal nur die "naive" Methode. Sie geht
davon aus, dass alle Farbnamen aus TK auch gleich in SVG vorhanden sind.
Muss ja nicht unbedingt so sein, so dass man hier ggf. noch eine
Übersetzungstabelle braucht. Ich habe trotzdem das Gefühl, dass man
hiermit schon einmal weit kommen kann.
Es folgen noch meine Source-Änderungen im Detail (siehe jeweils den
Marker "<--- here"):
Würde mich freuen zu hören, ob Du damit weiterkommst :-)
Viele Grüße
Thomas
linien.py:
self.line=self.c.create_line( x1, y1, x2, y2,
#arrow="both",
fill="blue", <--- here
joinstyle="round")
#width="5")
#arrowshape="180 80 10")
zeichenflaeche.py:
def enumerate_elements( self ):
"""
Aufzaehlen aller Elemente auf der Zeichenflaeche
"""
# Ermittle aktuelle Ausdehnung der Zeichnung
# (kann auch negative Koordination enthalten).
x1,y1,x2,y2 = self.c.cget("scrollregion").split()
elements = self.c.find_all()
for el in elements:
# x und y Koordination so verschieben, dass
# sie nicht negativ sind. (::2: Jedes zweite Element)
coord_x = [ x - float(x1) for x in self.c.coords(el)[0::2] ]
coord_y = [ y - float(y1) for y in self.c.coords(el)[1::2] ]
coords = list(zip(coord_x, coord_y) )
# pyId-Tag ermitteln
tags=self.c.gettags(el)
for tag in tags:
if tag.startswith("pyid"):
pyid_tag = tag
break;
if self.c.type(el) != "text":
yield (pyid_tag, self.c.type(el) ,coords,
self.c.itemcget(el, "fill" ) ) <--- here (*** Farbe ist
hierdurch im Tupel am Index 3 vorhanden ***)
else:
yield (pyid_tag, self.c.type(el) ,coords,
self.c.itemcget(el, "text" ), self.c.itemcget(el, "fill" )) <--- here
graphrenderer_frame.py:
def export_as_svg()
...
template5 = Template( '<polyline points="$points"
stroke="$stroke" />\n' ) <--- here
...
if element[1] == "line":
points = ""
for one_point in element[2]:
points = points + str(one_point[0]) + "," +
str(one_point[1]) + " "
f.write( template5.substitute( points=points,
stroke=element[3] ) ) <--- here
...
Mehr Informationen über die Mailingliste python-users