Meistens, wenn das W3C ein Format als Standard (oder genauer gesagt: Recommendation, Empfehlung) verabschiedet, ist die Fachwelt zufrieden. Allerdings kann das gemeine Volk damit oftmals wenig anfangen. Bestes Beispiel ist XML - es wird seit Jahren als Allheilsbringer verkündet, aber erst jetzt wird die Verbreitung von XML tatsächlich spürbar. Davor jedoch hat Otto Normalbenutzer nur wenig von der Technologie gehabt. Bei SVG - Scalable Vector Graphics - hätte das anders sein können. Die Idee dahinter ist nämlich sehr einfach: Es gibt im World Wide Web kein weit verbreitetes Vektorgrafikformat. GIF, JPEG und PNG, die von allen Browsern unterstützt werden, sind Pixelformate, die Grafiken werden dort also in einzelnen Bildpunkten abgespeichert. Sobald eine Grafik vergrößert werden muss, gehen Details verloren, denn die zusätzlichen erforderlichen Pixel werden aufgrund des vorhandenen Bildmaterials berechnet, sind aber nicht Teil der Grafik. Vektorgrafiken verfolgen einen anderen Ansatz. Das Bild wird aus geometrischen Figuren aufgebaut: Linien, Polygonen und Kreisen. Damit eignen sich Vektorpictureer nur wenig zur Darstellung von fotorealistischen Motiven, für alles andere jedoch können die Stärken des Formats genutzt werden: Eine Skalierung (Vergrößerung und Verkleinerung) ist ohne Qualitätsverlust möglich.
SVG hat damit eine Nische besetzt. Das Format ist komplett XML-basiert und somit bereits mit einem simplen Texteditor zu erstellen. Außerdem bietet das Format eine integrierte ECMAScript-Unterstützung, sodass es möglich ist, Skriptcode in die Grafik zu integrieren und damit auch dynamische Grafiken und Animationen zu erstellen. Die Liste der Features und Vorzüge von SVG ist lang und würde wohl einen eigenen Artikel füllen.
Wieso aber ist es für SVG doch noch ein sehr langer Weg bis zur Weltherrschaft? Das ist zu einem großen Teil durch den SVG-Hauptkonkurrenten, das Macromedia-Flash-Format, begründet. Flash basiert auch auf Vektorgrafiken und kann ebenfalls durch das mittlerweile sehr stark an ECMAScript angelehnte ActionScript programmiert werden. Flash ist ein binäres, nur in Teilen offengelegtes Format, das vom Hersteller Macromedia kontrolliert wird. Diese Nachteile des Platzhirschs sind allerdings, zumindest teilweise, ideologischer Natur, ein menschenlesbares Format ist nicht per definitionem besser als ein Binärformat. Dieses Argument zieht also nicht. Die Flash-Entwicklungsumgebung von Macromedia (Macromedia Flash) ist zudem ein sehr mächtiges Tool, zu dem es für SVG-Dateien nur wenige Entsprechungen gibt.
Ein weiteres Problem ist die Verbreitung - sowohl für Flash-Filme als auch für SVG-Grafiken wird ein Plugin benötigt. Das Flash-Plugin ist bei der Standardinstallation der meisten bekannten Webbrowser mit dabei, außerdem die einzige Third-Party-Komponente in Windows XP. Laut einer im September 2002 veröffentlichen Studie [2] setzen 97 Prozent aller Websurfer irgendeine Version des Flash-Plugins ein. Der Download ist zudem unter 200 KB, also auch mit einem Modem schnell übertragen. Etwas anders sieht es da bei SVG aus. Das zurzeit am weitesten verbreitete Plugin ist der Adobe SVG Viewer [3], der in seiner aktuellen Version 3 (Version 4 ist in der Entwicklung) mit etwa 3 MB zu Buche schlägt und entgegen anders lautender Gerüchte nicht automatisch beim beliebten Adobe Acrobat Reader mit dabei ist. Aufgrund einer Änderung der Mozilla-APIs funktioniert das Plugin unter dem Open Source-Browser und auch den neueren Netscape-Versionen nur eingeschränkt. Das Projekt, in Mozilla/Netscape eine integrierte SVG-Unterstützung anzubieten, ist so gut wie eingeschlafen. Hier ist also noch ein langer Weg zu gehen. Auch das recht neue SVG-Plugin von Corel [4] funktioniert nicht mit neueren Netscape-Versionen.
Neben den Hindernissen technischer Natur und der Akzeptanz des Formats sind einige SVG-Unterstützer häufig eher hinderlich denn hilfreich. Allzu oft wird wider besseren Wissens argumentiert, werden ideologische Gräben aufgezogen und so eine unlautere Diskussion geführt. Fakt ist: SVG ist zurzeit noch ein Exot, hat aber sehr gute Zukunftschancen. Es wäre nur hilfreich, wenn die Diskussion, das Pro und Contra gegenüber Flash (auch wenn einige Unverbesserliche es nicht wahrhaben möchten: Beide Formate haben ihre eigenen Vor- und Nachteile) etwas professioneller geführt werden würde.
Trotz all dieser negativen Punkte lohnt sich die Beschäftigung mit SVG, denn allzu oft hat sich gezeigt, dass eine W3C-Empfehlung sich auch tatsächlich durchgesetzt hat. Es gibt sogar schon eine Website, die vollständig auf SVG basiert (www.svgspider.com/), auch wenn sich hier über den Nutzen sicherlich streiten ließe.
Einige SVG-Beispiele
Wie bereits erwähnt, bei einer SVG-Datei handelt es sich um ein XML-Dokument. Durch einzelne Tags werden Elemente der Grafik angegeben. Hier ein kurzes Beispiel:<?xml version="1.0"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN""http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg width="300" height="100"><text x="150" y="75" style="color: red; font-size:36;">dot.net magazin<animate begin="0s" dur="3s" repeatCount="indefinite"attributeName="fill" values="#ff0000; #00ff00; #0000ff; #00ff00;#ff0000;" /></text></svg>
Von den grafischen Möglichkeiten einmal abgesehen, sind auch die Skriptmöglichkeiten von SVG nicht zu verachten. Die Integration von ECMAScript (der Standard für JavaScript) ermöglicht den Zugriff auf das DOM (Document Object Model) des SVG-Dokuments. Die SVG-Datei in Listing 1 beinhaltet ein noch leeres Textelement, in das mit DOM-Methoden die aktuelle Uhrzeit eingefügt wird.
Listing 1
<?xml version="1.0"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN""http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg onload="init(evt);" width="250px" height="100px"><defs><script type="text/ecmascript"><![CDATA[function init(evt) {svgdoc = evt.getTarget().getOwnerDocument();var uhrzeit = (new Date()).toLocaleString();var u = svgdoc.getElementById("uhr");var uz = svgdoc.createTextNode(uhrzeit);u.appendChild(uz);}]]></script></defs><text id="uhr" x="13" y="50" /></svg>
SVG mit ASP.NET erzeugen
Um SVG-Dateien mit ASP.NET zu generieren, müssen Ihre ASP.NET-Seiten, die den (dynamischen) SVG-Code generieren, den richtigen MIME-Typ zurückliefern. Fügen Sie dazu die folgende Anweisung in Ihre Seite ein:Response.ContentType = "image/svg+xml"
http://servername/skriptname.aspx?IE=.svg
SVG goes .NET: SVG#
Aufgrund des - zumindest momentanen - Nischenstatus gibt es in .NET natürlich keine direkte SVG-Unterstützung, aber eine ganze Reihe von XML-Funktionalitäten. Mit etwas Aufwand ist es damit möglich, SVG nachzupictureen und somit beispielsweise einen Viewer für das Grafikformat zu ermitteln. Ihre Kunden benötigen dann keinen SVG-Viewer, Sie selbst können aber (fast) alle Vorteile des Formats nutzen und es in Ihre Applikationen einbinden. Ein entsprechendes Projekt wird zurzeit bei SourceForge.net gehostet [5]. Es ist gemeinhin als SVG# bekannt, eine Anlehnung an die verwendete Programmiersprache C#. Ein weiterer geläufiger Projektname ist SharpVectors. Das ist der Name des Projekts in Visual Studio .NET.Nach dem Download der aktuellen Quellcodedistribution von der Projekthomepage oder dem direkten Bezug aus dem CVS-System bei SourceForge.net können Sie die Datei SharpVectors.sln durch Doppelklick in Visual Studio .NET öffnen. Dieses Projekt enthält mehrere Unterprojekte beziehungsweise Assemblies:
- SharpVectorObjectModel - eine möglichst genaue Abbildung des SVG-DOMs. Nach und nach werden hier alle Elemente der SVG-Spezifikation implementiert, ein Großteil ist bereits vorhanden.
- SharpVectorRenderingEngine - ein Renderer für SVG-Dateien. Hier werden SVG-Elemente in GDI-Anweisungen umgesetzt. Es wird also ein SVG-Plugin emuliert.
- SvgComponents - diese Assembly enthält zurzeit ein selbstgestricktes Web Control, SVGPictureBox. Es handelt sich hierbei um ein Steuerelement, das SVG-Dateien anzeigen kann. Hier wird also der Renderer integriert und ein Einbau der Komponente in .NET-Anwendungen ermöglicht.
- SharpVectorViewer - eine Demoapplikation, in der eine SVG-Datei angezeigt wird.
public GraphicsPath GetGraphicsPath(){if(gp == null){gp = new GraphicsPath();gp.AddLine(X1.AnimVal.Value,Y1.AnimVal.Value,X2.AnimVal.Value,Y2.AnimVal.Value);}return gp;}
Die nachfolgende Methode stammt aus dem Projekt SharpVectorRenderingEngine und liefert ein Bitmap zurück - hier wird also eine SVG-Grafik interpretiert und in Pixeldaten umgewandelt. Die Funktion selbst ist recht kurz, es wird der oberste Knoten genommen und dort die Methode Paint() aufgerufen. In dieser wird die SVG-Datei knotenweise mit GDI-Funktionen gezeichnet.
public Bitmap Render(){bmp = new Bitmap(Width, Height);PaintStatus ps = new PaintStatus();Graphics gr = Graphics.FromImage(bmp);gr.Clear(ColorBack);RootGraphicsNode.Paint(gr, ps);gr.Dispose();return bmp;}
Praxisprojekt
Erstellen Sie zunächst ein neues VB.NET-Projekt in Visual Studio .NET. Über Projekt | Verweis hinzufügen können Sie nun alle drei DLLs von SVG# hinzuzufügen. Dann ist es nämlich möglich, mittels Extras | Toolbox anpassen im Register .NET Framework-Komponenten das Benutzersteuerelement SvgPictureBox der Toolbox hinzufügen. Dann können Sie diese Komponente per Drag&Drop in Ihre Anwendung integrieren.
Zunächst einmal wird die erste der Schaltflächen mit Code hinterlegt. Auf Mausklick soll sich der Datei-öffnen-Dialog zeigen und der Benutzer eine SVG-Datei auswählen dürfen, deren Pfad dann in das Textfeld übertragen wird:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.ClickOpenFileDialog1.CheckFileExists = TrueOpenFileDialog1.Filter = "SVG-Dateien (*.svg)|*.svg|Alle Dateien|*.*"OpenFileDialog1.ShowDialog(Me)End SubPrivate Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOkTextBox1.Text = OpenFileDialog1.FileNameEnd Sub
SvgPictureBox1.SourceURL = TextBox1.Text
Dim temp As String = Path.GetTempFileName()Dim reader As StreamReader = New StreamReader(TextBox1.Text)Dim code As String = reader.ReadToEndreader.Close()Dim writer As StreamWriter = New StreamWriter(temp & ".xml", False)writer.Write(code)writer.Close()
Process.Start("iexplore.exe", "file:" & temp & ".xml")al.Add(temp)
Private Sub Form1_Unload(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClosedDim i As IntegerFor i = 0 To al.Count - 1File.Delete(al.Item(i))File.Delete(al.Item(i) & ".xml")NextEnd Sub
Listing 2
Imports System.IOPublic Class Form1Inherits System.Windows.Forms.Form#Region " Vom Windows Form Designer generierter Code "' ...#End RegionDim al As New ArrayList()Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.ClickDim fi As FileInfoDim fn As StringTryfi = New FileInfo(TextBox1.Text)fn = fi.FullNameCatchMessageBox.Show("Ungültiger Dateiname!")Exit SubEnd TryIf Not fn Is Nothing AndAlso fi.Exists ThenTrySvgPictureBox1.SourceURL = TextBox1.TextCatch ex As ExceptionMessageBox.Show("Fehler in der SVG-Datei!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)End TryElseMessageBox.Show("Datei existiert nicht!")End IfEnd SubPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.ClickOpenFileDialog1.CheckFileExists = TrueOpenFileDialog1.Filter = "SVG-Dateien (*.svg)|*.svg|Alle Dateien|*.*"OpenFileDialog1.ShowDialog(Me)End SubPrivate Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.ClickDim fi As FileInfoDim fn As StringTryfi = New FileInfo(TextBox1.Text)fn = fi.FullNameCatchMessageBox.Show("Ungültiger Dateiname!")Exit SubEnd TryIf Not fn Is Nothing AndAlso fi.Exists ThenTryDim temp As String = Path.GetTempFileName()Dim reader As StreamReader = New StreamReader(TextBox1.Text)Dim code As String = reader.ReadToEndreader.Close()Dim writer As StreamWriter = New StreamWriter(temp & ".xml", False)writer.Write(code)writer.Close()Process.Start("iexplore.exe", "file:" & temp & ".xml")al.Add(temp)Catch ex As ExceptionMessageBox.Show("Fehler beim Erstellen der temporären Datei!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)End TryElseMessageBox.Show("Datei existiert nicht!")End IfEnd SubPrivate Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOkTextBox1.Text = OpenFileDialog1.FileNameEnd SubPrivate Sub Form1_Unload(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClosedDim i As IntegerFor i = 0 To al.Count - 1File.Delete(al.Item(i))File.Delete(al.Item(i) & ".xml")NextEnd SubEnd Class
Links und Literatur
- [1] SVG-Homepage des W3C: www.w3.org/Graphics/SVG/
- [2] Verbreitung des Flash-Players: www.macromedia.com/software/player_census/flashplayer/version_penetration.html
- [3] Adobe SVG Viewer: www.adobe.com/svg/
- [4] Corel SVG Viewer: www.corel.com/svgviewer/
- [5] SVG# Projekthomepage: sourceforge.net/projects/svgdomcsharp/
- [6] Watt/Lilley/Ayers/George/Wenz/Hauser/Lindsey/Gustavsson, SVG Unleashed, Sams Publishing, 2002


