Webengineering_Roethig/Kapitel/11_SVG.tex
2017-07-24 15:24:17 +02:00

419 lines
18 KiB
TeX

\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]
<?xml version="1.0" ?>
<!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"
version="1.1"
width ="<Breite (in Pixeln, Millimetern, etc.)>"
height="<Höhe (in Pixeln, Millimetern, etc.)>"
viewBox="<x> <y> <Breite> <Höhe>">
<title>Titel der Grafik</title>
<desc>Beschreibung</desc>
<defs>
<!-- Für weitere Metadaten, z.B. CSS, JS, vordefinierte Objekte, ... -->
</defs>
<!-- eigentlich anzuzeigender Inhalt bestehend aus grafischen Elementen -->
</svg>
\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{<text>})
\item (Fast) Alle Tags bei \acs{SVG} sind leere tags (aber Metadaten \svg{<title>} 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 Q, jedoch wird hier als erster Kontrollpunkt der letzte aus der direkt zuvor festgelegten quadratischen Bézierkurve verwendet.
\item[\code{S s2x s2y ex ey}] ähnlich dem Kommando C, jedoch wird hier als erster Kontrollpunkt der letzte aus der direkt zuvor festgelegten Bézierkurve 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}
\begin{figure}[h!]
\centering
\includegraphics[width=0.84\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.