\chapter{SVG -- \acl{SVG}} \section{Grafikformate (im Web)}\index{Grafikformate} In \autoref{tbl:vergleich_raster_vektor} werden Raster- und Vektorgrafiken miteinander verglichen. \begin{table}[h] \centering \begin{tabular}{p{7.6cm}|p{7.6cm}} \textbf{Rastergrafiken} (Pixel-, Bitmap-Grafiken) & \textbf{Vektorgrafiken} \\ \midrule PNG, JPEG, GIF, (BMP) & SVG \\ \midrule Unterteilung der Darstellungsfläche in (meist gleichgroße, quadratische oder zumindest rechteckige) Teilflächen & Darstellung mithilfe von geometrischen Grundformen (\zB Kreisen, Linien, \ldots) \\ \midrule Zuordnung eines Farb- und/oder Helligkeits- und ggf. Transprarenzwertes zu jeder Teilfläche & Zuordnung von Position, Größe sowie Farb-, Helligkeits-, und Transparentwerten \\ \midrule $\oplus$ gängige Ein- und Ausgabegeräte arbeiten rasterbasiert & $\oplus$ nahezu unendliche Skalierbarkeit \\ \midrule $\oplus$ gut geeignet für fotorealistische Darstellungen & $\oplus$ gut geeignet für schematische, künstlich erzeugte Darstellungen \\ \midrule & $\ominus$ evtl. Zeit und rechenaufwändiges \enquote{Rendering} \\ \end{tabular} \caption{Vergleich von Raster- und Vektorgrafiken} \label{tbl:vergleich_raster_vektor} \end{table} \subsection{RGB-Format (für Rastergrafiken)}\index{RGB} \acs{RGB} hat getrennte Farbwerte für Rot, Grün und Blau, welche jeweils im Wertebereich von 0 bis 255 (8~Bit) liegen. Es bestitzt ein additives Farbmodell, \dash jeweils Farbe, je nach Helligkeit. Bei einer gängigen Auflösung von \zB 20 Megapixel: \begin{itemize}[noitemsep] \item besteht das Bild aus 20\,Mio. Teilflächen. \item braucht jedes Bild 60\,MByte Speicherplatz! \item[$\Rightarrow$] die meisten Bildformate komprimieren! \item[$\Rightarrow$] $2^{24} \approx 16\,Mio.$ Farben \end{itemize} Kompression bei: \begin{description} \item[GIF] \acf{GIF} (1987-er Jahre)\index{GIF} Farbtabelle, \dash maximal 256 verschiedene Farben aus den insgesamt verfügbaren 16\,Mio. sind in einem Bild gleichzeitig verwendbar.\newline $\Rightarrow$ Für jede Teilfläche sind nur 1\,Byte Information (als Indexwert auf die Farbtabelle) notwendig. $\Rightarrow$ in dieser Quantisierung auf 256 verschiedene Farbwerte steckt der Verlust bei \acs{GIF}, \textit{nicht} jedoch in der nachfolgenden Kompression. Das Kompressionsverfahren ist eine modifizierte Lauflängenkodierung (verlustfrei). Sonderfunktion: \begin{itemize}[noitemsep] \item Animated \acs{GIF} \item Transparenz (Markieren einer Farbe als \enquote{volltransparent}) \end{itemize} \end{description} \subsection{JPEG}\index{JPEG} \acf{JPEG} ist ein weiteres, häufig verwendetes Grafikformat. Hauptziel von \acs{JPEG}: \begin{itemize}[noitemsep] \item fotorealistische Darstellungen \item $\Rightarrow$ viel mehr als 256 Farben \item Farbformat: \acs{RGB} (ohne Alphakanal) \end{itemize} Komprimierung von \acs{JPEG}: \begin{itemize} \item \acf{DCT} als Vorstufe. Es handelt sich dabei um eine Mittelwertbildung über $8\times 8$-Pixelblöcke mit einer Abweichung der $4\times 4$/$2\times 2$/$1\times 1$-Pixelblöcke von jeweilig enthaltenden größeren Pixelblock (Abweichungen $\hat{=}$ DCT-Koeffizienten). \enquote{\textit{Im nächsten Schritt wird das Bild in $8\times 8$ große Pixelblöcke aufgetrennt. Jeder dieser Blöcke wird der diskreten Cosinus-Transformation unterzogen. Diese ist mit der Fourier-Transformation verwandt und wandelt die räumliche Information der Helligkeitswerte in eine Frequenz-Darstellung um. Die Umwandlung selbst ist verlustlos bis auf Rundungsfehler.}} -- Quelle: \url{https://www.tecchannel.de/a/jpeg,401190,3} \item Anwendung der Huffman-Kodierung\footnote{siehe auch \url{https://de.wikipedia.org/wiki/Huffman-Kodierung}} auf die Koeffizienten Prinzip der Huffman-Kodierung/Komprimierung: \newline Sortierung der Werte nach ihrer Häufigkeit des Vorkommens, \zB \begin{center} \begin{tabular}{rl} 1: & häufigster Wert \\ 01: & zweithäufigster Wert \\ 001: & dritthäufigster Wert \\ \end{tabular} \end{center} Bei den häufigen Werten wird Speicherplatz gespart, bei seltenen Werten braucht man jedoch mehr Speicherplatz. $\Rightarrow$ Einsparpotenzial nur bei stark unterschiedlich häufig vorkommenden Werten! \newline $\Rightarrow$ verlustfreie Komprimierung Verlust durch Ausgleich ähnlicher Koeffizienten auf gleiche Werte (Qualitätsfehler bei \acs{JPEG}) \newpage \item Nachfolgeformat: JPEG2000 \begin{itemize}[noitemsep] \item Unterstützung von RGB\textbf{A} \item keine allzugroße Verbreitung wegen Lizenzgebühren \item Unterstützung meist nur von kostenpflichtiger Software (\zB Photoshop, aber nicht \href{https://www.gimp.org/}{GIMP}) \end{itemize} \end{itemize} \subsection{PNG}\index{PNG} \acf{PNG} ist ein verlustfreies Grafikformat. Es besitzt folgende Eigenschaften: \begin{itemize}[noitemsep] \item mehrere Farbmodelle \begin{itemize}[noitemsep] \item indiziert (mit Farbtabelle) \item RGBA \end{itemize} \item immer verlustfrei \item geeignet für jegliche Art der Darstellung (künstliche \& photorealistisch) \item Problem bei photorealistischen Darstellungen: manchmal sehr großes Dateivolumen \end{itemize} \section{SVG}\index{SVG} \acf{SVG} ist ein Vektorgrafikformat, welches sich auch im Internet durchgesetzt hat. Geschichte:\index{SVG!Geschichte} \begin{description} \item[1998] zwei Ansätze für vektorbasiertes Grafikformat im Web: \begin{enumerate}[noitemsep] \item Microsoft \& Macromedia: \acf{VML} \item Adobe, IBM, NS, Sun: \acf{PGML} \end{enumerate} \item[10/1998] Anforderungen an vektorbasiertes Grafikformat für das Web \item[09/2001] \acs{SVG} 1.0 als \acs{W3C}-Standard \item[01/2003] \acs{SVG} 1.1 mit Fehlerbehebung und Modularisierung \item[04/2005] \acs{SVG} 1.2, aber außer \enquote{\acs{SVG} 1.2 Tiny} zurückgezogen \item[12/2016] Candidate Recommendation für \acs{SVG} 2.0 \end{description} Die Anzeige ist bei allen modernen Browsern \enquote{nativ} möglich. Sie kann auch in eine \acs{HTML}-Seite eingebettet werden. \begin{table}[h!] \centering \begin{tabular}{rl} \code{MIME}-Type. & \code{image/svg+xml} \\ File Extension: & \code{svg}, \code{.svgz} (gzip-komprimiert) \\ Format/Grundstruktur: & \textit{siehe \autoref{lst:svg_format}} \\ \end{tabular} \caption{Eigenschaften von SVG} \end{table} \bigskip \begin{lstlisting}[language=XML,caption=Grundstruktur einer SVG Datei,label=lst:svg_format] Titel der Grafik Beschreibung \end{lstlisting} \begin{description} \item[\code{viewBox}] optionales Attribut, um angezeigten Bereich des Koordinatensystems von 0 $\rightarrow$ Breite und 0 $\rightarrow$ Höhe auf x $\rightarrow$ x+Breite und y $\rightarrow$ y + Höhe zu setzen. \autoref{fig:svg_viewbox} auf Seite~\pageref{fig:svg_viewbox} verdeutlicht das Verhalten von \code{viewBox}\footnote{Quelle: \url{https://www.sarasoueidan.com/blog/svg-coordinate-systems/}}. \end{description} \begin{figure}[t!] \centering \includegraphics[width=0.64\textwidth]{Bilder/SVG_viewBoy.jpg} \caption{SVG -- \code{viewBox}} \label{fig:svg_viewbox} \end{figure} \subsection{Grundelemente}\index{SVG!Grundelemente} \begin{itemize}[noitemsep] \item Grafische Grundelemente werden jeweils über einen eigenen Tag dargestellt \item (Fast) Alle Parameter werden als Attribute angegeben (außer Textinhalt bei \svg{}) \item (Fast) Alle Tags bei \acs{SVG} sind leere tags (aber Metadaten \svg{} und \svg{<desc>} können bei jedem Tag als Kindelemente angegeben werden) \end{itemize} \begin{description} \item[Linie] \svg{<line x1="0" y1="0" x2="100" y2="100" />} \item[Kreis] \svg{<circle cx="<X-Koord>" cy="<Y-Koord.>" r="<Radius>" />} \item[Ellipse] \svg{<ellipse cx="<x>" cy="<y>" rx="<Radius X>" ry="<Radius Y>" />} Ellipsen liegen zunächst immer lotrecht im Koordinatensystem. \item[Rechteck] \svg{<rect x="<x>" y="<y>" width="Breite" height="Höhe" />} Optional gibt es noch \code{rx} und \code{ry} um die Ecken abzurunden. \item[Linienzug/Streckenzug] \svg{<polyline points="x1,y1 x2,y2"/>} Das \code{points} Attribut enthält Paare von x/y-Koordinaten für die zweidimensionalen Punkte. Getrennt durch Komma und/oder Whitespace, \dash folgendes wäre syntaktisch korrekt: \xml{<polyline points="5.5,3,8 7.5 1,1,1,11,111,1.1" />} \item[Polygon/geschlossener Streckenzug] \svg{<polygon points="x1,y1 x2,y2"/>} Wie der Linienzug. \item[quadratische Bézierkurve] Drei Punkte beschreiben die Kurve: \newline Anfangspunkt (AP), Endpunkt (EP) und Stützpunkt (SP)\newline \textit{Siehe \autoref{fig:bezierkurven} (links) auf Seite~\pageref{fig:bezierkurven} und nachfolgend \code{path Q}.\newline \autoref{sec:bezier} geht weiter auf Bézierkurven ein.} \item[kubische Bézierkurve] Vier Punkte beschreiben die Kurve: \newline Anfangspunkt (AP), Endpunkt (EP), Stützpunkt 1 (SP1) und Stützpunkt 2 (SP2)\newline \textit{Siehe \autoref{fig:bezierkurven} (rechts) auf Seite~\pageref{fig:bezierkurven} und nachfolgend \code{path C}} \item[Path] \enquote{Supertag} \xml{<path>}: eignet sich für Bézierkurven und (fast) alle anderen Objekte: Ein Attribut \code{d} (\enquote{data}) enthält Zeichenkommandos und Koordinaten.\newline \textbf{Kommandos} sind einzelne Buchstaben. \begin{itemize}[noitemsep] \item Großbuchstaben: Koordinaten sind absolut \item Kleinbuchstaben: relative Koordinaten zum jeweiligen Bezugspunkt (welcher sich nach der Abarbeitung jedes Kommandos ändert). \end{itemize} \begin{description} \item[\code{M x y}] Move: Bewegung zum Punkt (\code{x}, \code{y}), ohne etwas zu zeichnen \item[\code{L x y}] Line: Zeichne eine Strecke von aktuellen Bezugspunkt zum Punkt (\code{x}, \code{y}) \item[\code{H y}] Horizontal Line: Zeichne eine horizontale Linie zum Punkt ($x$, $y_{Bezugspunkt}$) \item[\code{V y}] Vertical Line: Zeichne eine vertikale Linie zum Punkt ($x_{Bezugspunkt}$, $y$) \item[\code{a}] arc Kreisbögen (Parameter selbst nachschauen) und Ellipsenbögen \item[\code{Q sx sy ex ey}] Quadratische Bézierkurve: Bézierkurve vom aktuellem Bezugspunkt über Stützpunkt (\code{sx}, \code{sy}) zum Endpunkt (\code{ex}, \code{ey}) \item[\code{C s1x s1y s2x s2y ex ey}] Kubische Bézierkurve: Bézierkurve vom aktuellem Bezugspunkt über die beiden Stützpunkte (\code{s1x}, \code{s1y}, \code{s2x}, \code{s2y}) zum Endpunkt (\code{ex}, \code{ey}) \item[\code{T ex ey}] ähnlich dem Kommando \code{Q}, jedoch \enquote{smooth}. Als \acs{AP} wird der vorherige \acs{EP} gewählt und als erster \acs{SP} wird der letzte aus der direkt zuvor festgelegten Bézierkurve am \acs{AP} der neuen Kurve gespiegelt und verwendet. \item[\code{S s2x s2y ex ey}] ähnlich dem Kommando \code{C}, jedoch \enquote{smooth}. Als \acs{AP} wird der vorherige \acs{EP} gewählt und als erster \acs{SP} wird der letzte aus der direkt zuvor festgelegten Bézierkurve am \acs{AP} der neuen Kurve gespiegelt und verwendet. \item[\code{Z}] Schließt den Pfad zum letzten Kontrollpunkt, der durch \code{M} gesetzt wurde (es gibt keinen Unterschied zwischen Groß- und Kleinschreibung). \end{description} \item[Text] \xml{<text x="x" y="y">zu schreibender Text</text>} Stellt eine Textzeile mit linkem oberen Eckpunkt (\code{x}, \code{y}) dar. \item[Gruppierung] \xml{<g><!-- andere Tags welche gruppiert werden sollen --></g>} Sinnvoll für Universalattribute \end{description} \vspace*{-2mm} \begin{figure}[h!] \centering \includegraphics[width=0.68\textwidth]{Bilder/Bezierkurven.png} \caption{Quadratische und kubische Bézierkurve} \label{fig:bezierkurven} \end{figure} \subsection{Universalattribute}\index{SVG!Universalattribute} \begin{description} \item[style] für \acs{CSS}-Angaben. Es gibt u.a. folgende \acs{CSS}-Properties: \begin{tabular}{rl} \code{\textbf{stroke}} & Strichfarbe \\ \code{\textbf{fill}}& Füllfarbe \\ \code{\textbf{opacity}}& Deckungsgrad (zwischen 0 und 1) \\ \code{\textbf{stroke-opacity}} &Deckungsgrad für Strich \\ \code{\textbf{fill-opacity}} &Deckungsgrad für Füllfläche \\ \end{tabular} Statt über \acs{CSS}-Properties gibt es auch die Möglichkeit, Darstellungsattribute direkt anzugeben, \zB \xml{<line x1="0" x2="5" y1="3" y2="27" stroke="red" />} \begin{Achtung}[frametitle=Achtung mit CSS!] \acs{CSS}-Angaben überschreiben die Werte der Darstellungsattribute! \end{Achtung} \begin{Hinweis}[frametitle=Hinweis zu SVG 2] Bei \acs{SVG} 2 werden auch die Geometrie-Attribute \code{x, y, x1, x2, y1, y2,cx, cy, rx, ry, r,... } zu Darstellungsattributen \enquote{promoted}/\enquote{befördert}. Damit sind darauf \zB auch \acs{CSS}-Animationen anwendbar. \newline Jedoch sorgt \css{* \{x:0;\}} dafür, dass alle Rechtecke an die X-Koordinate \code{0} positioniert werden (unabhängig vom Wert des Darstellungsattributs \code{x} im \xml{<rect/>}. \end{Hinweis} \item[\code{transform}] für geometrische Abbildungen \begin{description} \item[\code{transform="{}translate(dx dy)"}] Verschiebung um (\code{dx}, \code{dy}) (\code{dy} kann weggelassen werden, dann wird nur in X-Richtung verschoben) \item[\code{transform="{}scale(sx sy)"}] Skalierung um Faktor (\code{sx}, \code{sy}) (wird \code{sy} weggelassen, so ist \code{sy = sx}). Mithilfe von \code{scale} kann man zudem Elemente spiegeln: \begin{tabular}{ll} \code{scale(-1,-1)} & Punktspiegelung \\ \code{scale(1,-1)} & Achsenspiegelung x-Achse \\ \code{scale(-1,1)} & Achsenspiegelung y-Achse \\ \end{tabular} \item[\code{transform="{}rotate(angle cx cy)"}] Rotation um Winkel \code{angle} (Grad, nicht Radianten) um den optionalen Punkt (\code{cx, cy}) \item[\code{transform="{}skewX(angle)"}] Scherung horizontal um \code{angle} (Grad, nicht Radianten) \item[\code{transform="{}skewY(angle)"}] Scherung vertikal um \code{angle} (Grad, nicht Radianten) \end{description} Kombinierte Abbildung: \xml{transform="scale(3 7) translate(50 10)"} \newline $\Rightarrow$ erst Verschiebung, dann Skalierung! \item[Matrixtransformation] für beliebige affine Abbildungen: \code{matrix(a b c d e f)} \begin{center} $ \begin{pmatrix} x_{transf} \\ y_{transf} \\ 1 \\ \end{pmatrix} $ = $ \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \\ \end{pmatrix} $ $ \begin{pmatrix} x_{orig} \\ y_{orig} \\ 1 \end{pmatrix} $ \end{center} \textsf{\textbf{Beispiele}} \begin{center} \code{scale(sx sy)} als Matrixtransformation: $ \begin{pmatrix} x_{orig} \cdot sx \\ y_{orig} \cdot sy \\ 1 \\ \end{pmatrix} $ = $ \begin{pmatrix} sx & 0 & 0 \\ 0 & sy & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} $ $ \begin{pmatrix} x_{orig} \\ y_{orig} \\ 1 \end{pmatrix} $ \bigskip \code{translate(dx dy)} als Matrixtransformation: $ \begin{pmatrix} x_{orig} + dx \\ y_{orig} + dy \\ 1 \\ \end{pmatrix} $ = $ \begin{pmatrix} 1 & 0 & dx \\ 0 & 1 & dy \\ 0 & 0 & 1 \\ \end{pmatrix} $ $ \begin{pmatrix} x_{orig} \\ y_{orig} \\ 1 \end{pmatrix} $ \end{center} \end{description} \subsection{Bézierkurve}\label{sec:bezier} Konstruktion mithilfe des Algorithmus von de Casteljau\footnote{siehe auch \url{https://de.wikipedia.org/wiki/De-Casteljau-Algorithmus}}. \begin{figure}[ht] \centering \includegraphics[width=0.6\textwidth]{Bilder/Quadratische_Bezierkurve_2.png} \caption{Erzeugung einer quadratischen Bézierkurve} \label{fig:bezierkurve_quadratisch_2} \end{figure} Wie in \autoref{fig:bezierkurve_quadratisch_2} gezeigt wird, liegt $O$ auf der Bézierkurve. Die Bézierkurve $A-B-C$ lässt sich als Konkatenation der beiden Bézierkurven $A-P-O$ und $O-R-C$ darstellen. Dadurch ist eine rekursive Anwendung möglich! Dies wird soweit ausgeführt, bis die Auflösung des Ausgabegerätes erreicht ist.