decocode decocode deco    

Scalable Vector Graphics (SVG) #

Übersicht
Linien
Rechtecke
Kreise und Ellipsen

SVG ist ein textbasiertes Datenformat für Vektorgrafiken. Der Vorteil von Vektorgrafiken gegenüber Rastergrafiken besteht vor allem in der beliebigen verlustfreien Skalierbarkeit. Das heißt, eine Vektorgrafik kann beliebig vergrößert werden, ohne dass die Grafik an Konturschärfe verliert oder grobe Pixel sichtbar werden. Dies wird erreicht, indem das Bild nicht Bildpunkt für Bildpunkt aufgelöst, sondern auf seine geometrischen Inhalte abstrahiert wird. Für ein Rechteck werden beispielsweise lediglich dessen Position, Kantenlänge, Kontur- und Füllfarbe benötigt, um es zu beschreiben. Auf diese Weise kann der Speicherbedarf einer Vektorgrafik sehr gering gehalten werden. Auf der anderen Seite ist der Rechenaufwand für die Darstellung einer Vektorgrafik unter Umständen wesentlich höher als bei einer Rastergrafik. Auch ist nicht jede Art von Bild für die Darstellung als Vektorgrafik geeignet. Während man Fotos oder gescannte Gemälde sicherlich besser als Rastergrafik speichert, können Logos, Diagramme, Landkarten oder Comics durchaus gut als Vektorgrafik dargestellt werden, da sie häufig überwiegend aus Flächen und Linien bestehen.

SVG ist nun eine Auszeichnungssprache, mit der Vektorgrafiken beschrieben werden können. Diese Sprache erinnert in ihrem Aufbau stark an HTML. Dies ist wenig verwunderlich, da sowohl SVG als auch HTML quasi »Dialekte« des zugrunde liegenden SGML sind. Da der Inhalt einer SVG-Datei ausschließlich aus Text besteht, ist es auch möglich, SVGrafiken dynamisch mittels PHP zu erzeugen.

Neben der manuellen Erstellung, die in diesem Tutorial behandelt wird, können SVGrafiken auch mit eigenständigen Editoren wie beispielsweise Inkscape erstellt werden. Die Standard-Konformität des SVG-Quelltextes kann z. B. mit dem W3C-Validator überprüft werden.

Das Grundgerüst einer SVG-Datei sieht folgendermaßen aus:

Quelltext auswählen
1
2
3
4
5
6
7
8
9
10
11
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg xmlns='http://www.w3.org/2000/svg'
     xmlns:xlink='http://www.w3.org/1999/xlink'
     xmlns:ev='http://www.w3.org/2001/xml-events'
     version='1.1' baseProfile='full'
     width='800px' height='600px'>
 
<!-- Hier kommen die Angaben zur Grafik -->
 
</svg>

Vor allem die Werte für die Breite und Höhe der Grafik (width und height) wird man natürlich anpassen müssen. Die Angabe baseProfile bezieht sich auf die möglichen Ausgabeprofile.

• Maße können unter anderem in Pixeln oder Millimeter angegeben werden.
• Das Koordinatensystem hat seinen Ursprung oben/links.
• Objekte dürfen die Bilddimensionen überragen.
• Koordinaten geben das Zentrum einer Linie an.
• Objekte können mit CSS formatiert werden.
• Der Hintergrund von SVGrafiken ist standardmäßig transparent.
• Objekte überlagern sich standardmäßig in der Reihenfolge ihres Auftretens.
• Internet Explorer unterstützt SVG erst ab Version 9.

Zunächst sollen hier die grafischen Primitive abgehandelt werden, die mit SVG beschrieben werden können. Weitere Informationen: W3C

Linien #

Linien werden mit dem <line>-Tag definiert. Obligatorische Attribute sind die Koordinaten für den Anfangspunkt (x1, y1) und den Endpunkt (x2, y2) der Linie sowie die Linienfarbe (stroke). Wird keine Linienfarbe angegeben (wie in Beispiel line0), so wird auch keine Linie gezeichnet.

Weitere Attribute sind:
stroke-width für die Linienstärke (default: 1px)
stroke-opacity für die Opazität (Deckkraft) der Linie (default: 1.0)
stroke-linecap für die Darstellung des Abschlusses einer Linie (butt, round, square)
stroke-dasharray für Unterbrechungen
stroke-dashoffset steuert den Beginn der Unterbrechungen

Quelltext auswählen
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' version='1.1' baseProfile='full' width='350px' height='150px'>
  <line id='line0' x1='10' y1='10' x2='340' y2='10' />
  <line id='line1' x1='10' y1='20' x2='340' y2='20' stroke='cyan' />
  <line id='line2' x1='10' y1='30.5' x2='340' y2='30.5' stroke='cyan' />
  <line id='line3' x1='10' y1='40' x2='340' y2='40' stroke='cyan' stroke-width='2px' />
  <line id='line4' x1='10' y1='55' x2='340' y2='55' stroke='cyan' stroke-width='10px' stroke-dasharray='20,5' stroke-dashoffset='8' />
  <line id='line5' x1='330' y1='10' x2='10' y2='120' stroke='green' stroke-width='10px' />
  <line id='line6' x1='10' y1='75' x2='340' y2='75' stroke='cyan' stroke-width='10px' stroke-linecap='square' stroke-opacity='.5' />
  <line id='line7' x1='10' y1='95' x2='340' y2='95' stroke='cyan' stroke-width='10px' stroke-linecap='round' />
</svg>

Unten sieht man die von dem Skript erzeugte Grafik. Die oberste sichtbare Linie (line1) hat im Skript die Breite 1px (da keine Breite angegeben wurde), während sie in der Grafik über zwei Pixel ausgedehnt wird. Die Ursache hierfür liegt in der Position, da die Angabe y1='20' das Zentrum der Linie genau auf die Grenze zwischen zwei Pixelzeilen verortet. Als Kompromiss werden daraufhin die Pixelzeilen ober- und unterhalb dieses Wertes mit der halben Opazität gefüllt. Möchte man dieses Verhalten verhindern, so muss man entweder einen durch 2 teilbaren Wert für die Linienstärke angeben oder die Linie auf die Mitte einer Pixelzeile verorten, wie im Beispiel bei line2 mit dem Wert y1='30.5'. Dieses Verhalten ist allerdings nur bei einer Skalierung von 100 % relevant, da die Darstellung bei einer anderen Vergrößerung oder Verkleinerung natürlich entsprechend anders erfolgt.
Die Linie line3 besitzt nun wirklich 2 Pixel Stärke, und Linie line4 ist 10 Pixel stark. Diese Linie wurde zusätzlich durch das Attribut stroke-dasharray unterbrochen. Über das Attribut stroke-dashoffset kann der Beginn des Intervalls der Unterbrechung beeinflusst werden.
Die nächste Linie line6 besitzt zusätzlich die Attribute stroke-linecap='square' und stroke-opacity='.5'. Das bedeutet, dass die Linie an beiden Enden mit einem square (Rechteck) abgeschlossen (und dadurch etwas länger) wird und zu 50 % opak ist. Linie line7 wird durch das Attribut stroke-linecap='round' an den Enden abgerundet.
Die grüne diagonale Linie line5 wird nur von den letzten beiden Linien überdeckt, da sie im Skript vor diesen definiert wurde.

SVG-Beispiel für Linien SVG-Beispiel für Linien

Rechtecke #

Rechtecke werden mit dem <rect>-Tag definiert. Obligatorische Attribute sind die Koordinaten für die linke obere Ecke (x, y), die Dimensionen (width, height) sowie die Linienfarbe (stroke) und Füllfarbe (fill). Wird keine Linienfarbe angegeben (wie in Beispiel rectTopRight), so wird auch keine Linie gezeichnet. Wird keine Füllfarbe angegeben, so wird das Rechteck schwarz gefüllt. Möchte man ein Rechteck ganz ohne Füllung, so lautet das Attribut fill='none'.

In dem folgenden Beispiel sind die Formatierungen allerdings nicht mittels der Attribute in den SVG-Tags vorgenommen worden, sondern mittels CSS. Wie man die Formatierungen vornimmt ist Geschmacksache, die Methoden in diesem Skript dienen nur der Veranschaulichung. Ich persönlich empfinde ein Skript übersichtlicher, wenn die Tags möglichst frei von Format-Attributen sind.

Quelltext auswählen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' version='1.1' baseProfile='full' width='350px' height='180px'>
  <style type='text/css'>
    .rectC { fill:yellow; stroke:blue; stroke-width:1px; }
    #rectBottomLeft { fill:green; opacity:.8; stroke:red; stroke-width:6px; stroke-opacity:1; }
    #rectBottomRight { fill:cyan; opacity:1; stroke:red; stroke-width:10px; stroke-opacity:.5; }
    #rectExtra { fill:blue; stroke:red; stroke-width:16px; stroke-linejoin:bevel; }
  </style>
  <rect id='rectTopLeft' x='10' y='10' width='80' height='60' rx='10' style='fill:none;opacity:.8;stroke:red;stroke-width:6px;stroke-opacity:1;stroke-dasharray:14,4;stroke-dashoffset:12;' />
  <rect id='rectTopRight' x='130' y='10' width='120' height='60' rx='40' ry='20' />
  <rect id='rectCenter' x='50.5' y='40.5' width='120' height='90' class='rectC' />
  <rect id='rectBottomLeft' x='10' y='100' width='80' height='60' />
  <rect id='rectBottomRight' x='130' y='100' width='80' height='60' />
  <rect id='rectExtra' x='270' y='20' width='50' height='120' />
</svg>

Für die beiden oberen Rechtecke wurden zusätzliche Angaben für abgerundete Ecken gemacht, wobei die Abrundungen auch elliptisch ausgeführt werden können. Dann muss man für rx (horizontale Abrundung) und ry (vertikale Abrundung) eigene Werte angeben (rectTopRight). Soll die Abrundung gleichförmig erfolgen, so genügt eine der beiden Angaben (rectTopLeft).

Die Attribute stroke-dasharray und stroke-dashoffset bewirken die Unterbrechungen der Konturlinie von rectTopLeft.

Das Zentrum der Konturlinie verläuft genauso wie bei einer regulären Linie entlang der Außenkanten des Rechtecks. Das hat für die Abmessungen des Rechtecks zur Folge, dass an jeder Außenkante nur die halbe Strichstärke der Konturlinie zu den Außenmaßen addiert werden muss, um die Gesamtgröße zu ermitteln. Andererseits verringert sich die Innenfläche an jeder Kante ebenfalls um die halbe Strichstärke der Konturlinie. Dies wird besonders deutlich, wenn man die Deckkraft der Konturlinie verringert. Dann scheinen die Umgebung des Rechtecks und das Rechteck selbst jeweils zur Hälfte unter der Konturlinie durch (rectBottomRight).

Verringert man die Deckkraft des gesamten Rechtecks (rectBottomLeft), so wird auch die Konturlinie transparenter, ansonsten muss man das Attribut fill-opacity verwenden.

Das Rechteck rectExtra demonstriert die Wirkung des Attributs stroke-linejoin. Mögliche Werte sind miter (Gehrung), round (Rundung) und bevel (Fase).

Hier noch einmal die wichtigsten Attribute zur Formatierung:
stroke (none)
stroke-width (1px)
stroke-opacity (1.0)
stroke-dasharray
stroke-dashoffset
stroke-linejoin (miter, round, bevel)
fill (black)
fill-opacity (1.0)
opacity (1.0)

SVG-Beispiel für Rechtecke SVG-Beispiel für Rechtecke

Kreise und Ellipsen #

Kreise werden durch das <circle>-Tag und Ellipsen durch das <ellipse>-Tag definiert. In beiden Fällen muss der Mittelpunkt des Objekts durch die Koordinaten cx und cy angegeben werden. Bei Kreisen wird der Radius über das Attribut r angegeben, während bei Ellipsen die zwei Radien rx und ry angegeben werden müssen.

Quelltext auswählen
1
2
3
4
5
6
7
8
9
10
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' version='1.1' baseProfile='full' width='350px' height='180px'>
  <style type='text/css'>
    #circle1 { fill:yellow; }
    #ellipse1 { stroke:red; stroke-width:10px; stroke-opacity:.6; fill:blue; }
  </style>
  <circle id='circle1' cx='80' cy='80' r='50' />
  <ellipse id='ellipse1' cx='180' cy='100' rx='100' ry='50' />
</svg>

Die farbliche Formatierung folgt prinzipiell den gleichen Regeln wie bei der Formatierung von Rechtecken.

SVG-Beispiel für Kreise SVG-Beispiel für Kreise

Informationen zu komplexeren Formen wie polyline, polygon und path auf der nächsten Seite.