Effekthascherei

Die Klasse bietet Unterstützung zum Laden von Bildern über ihre Eigenschaft UriSource. Das
Ergebnis kann beispielsweise der Eigenschaft
Source der Klasse Image zugewiesen
werden, um das Bild anzuzeigen. Die Klasse
erkennt anhand der von BitmapSource
geerbten Funktionalität und anhand der
installierten Codecs welches Format ein
Bild besitzt und lädt es.

Die WPF liefert bereits
einige Decoder- und Encoderklassen
mit. Basisklassen sind hier die Klassen BitmapEncoder und BitmapDecoder. Davon
abgeleitet sind die konkreten Klassen für
die verschiedenen Bildformate. Wie Tabelle 1 zeigt, gibt es für zwei Decoder kein
entsprechendes Äquivalent in den Encoderklassen.

Tabelle 1: Encoder und Decoder zur Bildverarbeitung

Um ein Bild über einen Decoder zu laden,
wird ein Stream erzeugt und dem Decoder
übergeben. Alternativ kann auch ein
URI übergeben werden. Die weiteren Parameter
werden über ihre Standardwerte
angegeben. Um das Bild später in einer
Image-Komponente anzuzeigen, kann ein
Frame einer BitmapSource zugewiesen
werden (oder direkt der Eigenschaft Source
eines Images).

FileStream fs = new FileStream("images\Nelly.jpg",
FileMode.Open);
JpegBitmapDecoder jpgImg = new JpegBitmapDecoder(fs,
BitmapCreateOptions.None, BitmapCacheOption.Default);
BitmapSource bs = jpgImg.Frames[0];

Um ein Bild von einem Format in ein anderes
Format zu konvertieren, wird ein
Encoder verwendet. Dieser besitzt eine
Eigenschaft Frames, die auch über eine
Methode Add() verfügt, um weitere Bilder
aufzunehmen. Als Parameter wird ein
einzelner Frame übergeben, wie er z.B.
im vorigen Beispiel aus dem eingelesenen
JPG-Bild verwendet wurde. Der Encoder
besitzt außerdem eine Methode Save(),
um das aktuelle Bild in einem Stream zu
speichern:

PngBitmapEncoder pngEnc = new PngBitmapEncoder();
pngEnc.Frames.Add(jpgImg.Frames[0]);
FileStream fsPng = new FileStream("images\Nelly.png",
FileMode.Create);
pngEnc.Save(fsPng);

Eine andere Form der Konvertierung eines
Bildes kann zum Beispiel die Umwandlung in ein Graustufenbild sein. Dazu wird
die Klasse FormatConvertedBitmap verwendet.
In die Methoden BeginInit() und
EndInit() wird das Erstellen eines Bildes
eingeschlossen. Der Eigenschaft Source
wird eine BitmapSource übergeben, über
die Eigenschaft DestinationFormat wird
das Pixelformat angegeben, welches über
eine der Eigenschaften der Klasse PixelFormats angegeben wird:

FormatConvertedBitmap fcb = new FormatConvertedBitmap();
fcb.BeginInit();
fcb.Source = bs;
fcb.DestinationFormat = PixelFormats.Gray8;
fcb.EndInit();

Das Ergebnis der Konvertierung kann wiederum
direkt der Eigenschaft Source einer
Image-Komponente zugewiesen werden,
um das Bild anzuzeigen.

Bitmap-Effekte

Möchten Sie, dass ein Foto nicht mehr ganz
scharf angezeigt wird (zum Beispiel um die
Falten im Gesicht zu verbergen) oder ein
Bild mit einem Schatten versehen wird –
mit Bitmap-Effekten ist das kein Problem
mehr. Die WPF stellt mehrere Klassen für
Bitmap-Effekte bereit, wobei die Klasse
BitmapEffect die Basisklasse der anderen
darstellt. Ein Typ dieser Klasse kann der
Eigenschaft BitmapEffect zugewiesen
werden, die alle Komponentenklassen wie
Button oder Image von der Klasse UIElement
erben. Von den verbleibenden Klassen
dient beispielsweise die Klasse BitmapEffectGroup dazu, mehrere Bitmapeffekte
zusammenzufassen, damit man diese
der Eigenschaft BitmapEffect zuweisen
kann. Der folgende Sourcecode zeigt den
Grundaufbau der Verwendung der Bitmapeffekte
in XAML, wobei hier eine
Effektgruppe zum Einsatz kommt. Soll
nur ein Effekt angewendet werden, wird
dieser direkt unter dem Element Image.BitmapEffect angeordnet.


...Bitmapeffektklasse...
...Bitmapeffektklasse...

Mit den Effektklassen können Sie auch
Teileffekte erzeugen, die sich nur auf einen
bestimmten Bereich eines Elements auswirken.
Dazu wird die Eigenschaft BitmapEffectInput verwendet. Der Bereich für
den Effekt wird über die Eigenschaft Area-
ToApplyEffect
in Form einer Rect-Angabe
(X, Y, Breite, Höhe) ausgewählt. Entweder
geben Sie ihn prozentual im Bereich
von 0 bis 1 oder in Pixeln an. Dies hängt
von der Einstellung in der Eigenschaft
AreaToApplyEffectUnits ab. Wird der
Wert Absolute angegeben, werden Pixel
verwendet, durch die Übergabe von RelativeToBoundingBox
dagegen prozentuale
Werte. Der folgende Code wählt beispielsweise
den mittleren Bereich eines Rechtecks
der Größe 200 x 200 aus:

PngBitmapEncoder pngEnc = new PngBitmapEncoder();
pngEnc.Frames.Add(jpgImg.Frames[0]);
FileStream fsPng = new FileStream("images\Nelly.png",
FileMode.Create);
pngEnc.Save(fsPng);

Beispielhaft wird zum Abschluss die Effektklasse
BlurBitmapEffect vorgestellt.
Die Auswirkungen der anderen Effektklassen
werden in Abbildung 3 gezeigt:

Abb. 3: Verschiedene Effekte im Überblick (die Pflanze wurde inzwischen gegossen)

Über Blur-Effekte wird der Hintergrund
der betreffenden Komponente verwischt
(verschwommen) dargestellt. Über die Eigenschaft
Radius wird die Stärke der Verwischung
in 1/96 Inch eingestellt, mittels
der Eigenschaft KernelType der verwendete
Algorithmus (Box – schneller aber qualitativ
etwas schlechter, Gaussian – aufwändiger)
festgelegt:

Die weiteren Effektklassen erzeugen zum
Beispiel Schlagschatten (DropShadowBitmapEffect), Glüheffekte (OuterGlowBitmapEffect), Außenränder (BevelBitmapEffect)
und Prägungen (EmbossBitmapEffect).
Eine Prägung lässt von der
ursprünglichen Darstellung in den meisten
Fällen nicht mehr viel übrig. Sie schält
bei einem Bild sozusagen eine Oberflächenstruktur
heraus, deren Stärke über
die Eigenschaft Relief zwischen 0 und 1
einstellt werden kann.

Die Basics werden abgedeckt

Auch in Bezug auf die Bildverarbeitung
hat die Windows Presentation Foundation
eine Menge zu bieten. Natürlich wird dadurch
keine professionelle Grafikbibliothek
ersetzt, allerdings reichen die angebotenen
Klassen für viele Standardaufgaben
völlig aus. Als mögliche Ideen für weitere
„Spielereien“ seien die Erstellung von Slideshows
und Einblendeffekte (über Transparenzmasken)
genannt. Obwohl dieses
Mal nur die Anwendung auf Bilder beschrieben
wurde, lassen sich alle Effekte
oder die Transparenzmasken auf alle von
der Klasse UIElement abgeleiteten Klassen
anwenden – somit auf sämtliche sichtbaren
Komponenten.

Nachdem Dirk Frischalowski sein Buch zur WPF fertig gestellt hat, widmet er sich schon dem nächsten Projekt, einem Buch zu Expression Blend. Das
wird allerdings noch etwas dauern. Bereits begonnen
hat er damit, sein lange angekündigtes WPFTutorial
unter www.gowinfx.de wieder aufleben zu
lassen.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.