Übersicht über die Bildverarbeitung

Dieses Thema enthält eine Einführung in die Microsoft Windows Presentation Foundation Imaging-Komponente. WPF Imaging ermöglicht es Entwicklern, Bilder anzuzeigen, zu transformieren und zu formatieren.

WPF Imaging-Komponente

WPF-Imaging bietet deutliche Verbesserungen für die Bildverarbeitungsfähigkeiten in Microsoft Windows. Die Bildverarbeitungsfähigkeiten, etwa das Anzeigen einer Bitmap oder das Verwenden eines Bilds für ein allgemeines Steuerelement, waren bisher auf das Microsoft Windows Graphics Device Interface (GDI) oder die Microsoft Windows GDI+-Bibliotheken angewiesen. Diese APIs stellen Baseline-Bildverarbeitungsfähigkeiten bereit, verfügen aber nicht über Features wie die Unterstützung für Codec-Erweiterbarkeit und hochwertige Bilder. WPF Imaging wurde entworfen, um die Nachteile von GDI und GDI+ zu beheben und einen neuen Satz von APIs bereitzustellen, um Bilder in den Anwendungen anzeigen und verwenden können.

Es gibt zwei Zugriffsmöglichkeiten auf die WPF Imaging-API: eine verwaltete Komponente und eine nicht verwaltete Komponente. Die nicht verwaltete Komponente stellt die folgenden Features bereit.

  • Erweiterbarkeitsmodell für neue oder proprietäre Bildformate.

  • Verbesserte Leistung und Sicherheit bei nativen Bildformaten, einschließlich Bitmap (BMP), Joint Photographics Experts Group (JPEG), Portable Network Graphics (PNG), Tagged Image File Format (TIFF), Microsoft Windows Media Photo, Graphics Interchange Format (GIF) und Symbol (ICO).

  • Beibehaltung von Bilddaten mit hoher Bittiefe von bis zu 8 Bits pro Kanal (32 Bits pro Pixel).

  • Nicht destruktive Bildskalieren, Zuschneiden und Drehungen.

  • Vereinfachte Farbverwaltung.

  • Unterstützung für in der Datei enthaltene proprietäre Metadaten.

  • Die verwaltete Komponente nutzt die nicht verwaltete Infrastruktur, um die nahtlose Integration von Bildern mit anderen WPF-Funktionen bereitzustellen, z. B. Benutzeroberfläche (UI), Animation und Grafiken. Die verwaltete Komponente profitiert ebenfalls vom Codec-Erweiterbarkeitsmodell der Bildverarbeitung in Windows Presentation Foundation (WPF), was eine automatische Erkennung neuer Bildformate in WPF-Anwendungen ermöglicht.

Der Großteil der verwalteten WPF-Imaging-API befindet sich im System.Windows.Media.Imaging-Namespace, obwohl mehrere wichtige Typen, z. B. ImageBrush und ImageDrawing im System.Windows.Media-Namespace vorhanden sind und Image sich im System.Windows.Controls-Namespace befindet.

Dieses Thema enthält zusätzliche Informationen über die verwaltete Komponente. Weitere Informationen über die nicht verwaltete API finden Sie in der Dokumentation Nicht verwaltete WPF Imaging-Komponente.

WPF-Bildformate

Ein Codec wird zum Decodieren und Codieren eines bestimmten Medienformats verwendet. WPF Imaging umfasst einen Codec für BMP-, JPEG-, PNG-, TIFF-, Windows Media Photo-, GIF- und ICON-Bildformate. Anhand jedes einzelnen Codecs können Anwendungen das entsprechende Bildformat decodieren und, mit Ausnahme von ICON, Codieren.

BitmapSource ist eine wichtige Klasse, die beim Decodieren und Codieren von Bildern verwendet wird. Sie ist der grundlegende Baustein der WPF Imaging-Pipeline und stellt einen einzelnen konstanten Satz von Pixeln mit einer bestimmten Größe und Auflösung dar. Ein BitmapSource-Objekt kann ein einzelner Frame eines Multiframebilds sein, oder es kann das Ergebnis einer Transformation sein, die mit einem BitmapSource-Objekt ausgeführt wurde. Es ist das übergeordnete Element vieler der primären Klassen, die in WPF Imaging verwendet werden, etwa BitmapFrame.

Ein BitmapFrame-Objekt wird verwendet, um die tatsächlichen Bitmap-Daten eines Bildformats zu speichern. Viele Bildformate unterstützen lediglich ein einziges BitmapFrame-Objekt, obwohl Formate wie GIF und TIFF mehrere Frames pro Bild unterstützen. Rahmen werden von Decodern als Eingabedaten verwendet und zur Erstellung der Bilddateien an Encoder übergeben.

Im folgenden Beispiel wird veranschaulicht, wie ein BitmapFrame-Objekt aus einem BitmapSource-Objekt erstellt und dann einem TIFF-Bild hinzugefügt wird.

BitmapSource image5 = BitmapSource.Create(
    width,
    height,
    96,
    96,
    PixelFormats.Indexed1,
    BitmapPalettes.WebPalette,
    pixels,
    stride);

FileStream stream5 = new FileStream("palette.tif", FileMode.Create);
TiffBitmapEncoder encoder5 = new TiffBitmapEncoder();
encoder5.Frames.Add(BitmapFrame.Create(image5));
encoder5.Save(stream5);
Dim image5 As BitmapSource = System.Windows.Media.Imaging.BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, BitmapPalettes.WebPalette, pixels, stride)

Dim stream5 As New FileStream("palette.tif", FileMode.Create)
Dim encoder5 As New TiffBitmapEncoder()
encoder5.Frames.Add(BitmapFrame.Create(image5))
encoder5.Save(stream5)

Decodieren von Bildformaten

Beim Decodieren von Bildern wird das Bildformat in Bilddaten übersetzt, die vom System verwendet werden können. Die Bilddaten können dann verwendet werden, um das Bild anzuzeigen und zu verarbeiten oder um es in ein anderes Format zu codieren. Die Decoderauswahl basiert auf dem Bildformat. Der Codec wird automatisch ausgewählt, wenn kein bestimmter Decoder angegeben wird. Die Beispiele im Abschnitt Anzeigen von Bildern in WPF veranschaulichen die automatische Decodierung. Decoder für benutzerdefinierte Formate, die mithilfe der nicht verwalteten WPF Imaging-Schnittstellen entwickelt und im System registriert sind, werden automatisch in die Decoderauswahl eingebunden. Dadurch können benutzerdefinierte Formate, automatisch in WPF-Anwendungen angezeigt werden.

Das folgende Beispiel veranschaulicht die Verwendung eines Bitmapdecoders, um ein Bild im BMP-Format zu decodieren.


// Open a Uri and decode a BMP image
System::Uri^ myUri = gcnew System::Uri("tulipfarm.bmp", UriKind::RelativeOrAbsolute);
BmpBitmapDecoder^ decoder2 = gcnew BmpBitmapDecoder(myUri, BitmapCreateOptions::PreservePixelFormat, BitmapCacheOption::Default);
BitmapSource^ bitmapSource2 = decoder2->Frames[0];

// Draw the Image
Image^ myImage2 = gcnew Image();
myImage2->Source = bitmapSource2;
myImage2->Stretch = Stretch::None;
myImage2->Margin = System::Windows::Thickness(20);

// Open a Uri and decode a BMP image
Uri myUri = new Uri("tulipfarm.bmp", UriKind.RelativeOrAbsolute);
BmpBitmapDecoder decoder2 = new BmpBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource2 = decoder2.Frames[0];

// Draw the Image
Image myImage2 = new Image();
myImage2.Source = bitmapSource2;
myImage2.Stretch = Stretch.None;
myImage2.Margin = new Thickness(20);
' Open a Uri and decode a BMP image
Dim myUri As New Uri("tulipfarm.bmp", UriKind.RelativeOrAbsolute)
Dim decoder2 As New BmpBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
Dim bitmapSource2 As BitmapSource = decoder2.Frames(0)

' Draw the Image
Dim myImage2 As New Image()
myImage2.Source = bitmapSource2
myImage2.Stretch = Stretch.None
myImage2.Margin = New Thickness(20)

Codieren von Bildformaten

Bei der Bildcodierung werden Bilddaten in ein bestimmten Bildformat übersetzt. Die codierten Bilddaten können dann zum Erstellen neuer Bilddateien verwendet werden. WPF Imaging stellt Encoder für jedes der oben beschriebenen Bildformate bereit.

Das folgende Beispiel veranschaulicht die Verwendung eines Encoders, um ein neu erstelltes Bitmapbild zu speichern.

FileStream^ stream = gcnew FileStream("new.bmp", FileMode::Create);
BmpBitmapEncoder^ encoder = gcnew BmpBitmapEncoder();
TextBlock^ myTextBlock = gcnew TextBlock();
myTextBlock->Text = "Codec Author is: " + encoder->CodecInfo->Author->ToString();
encoder->Frames->Add(BitmapFrame::Create(image));
encoder->Save(stream);
FileStream stream = new FileStream("new.bmp", FileMode.Create);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString();
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);
Dim stream As New FileStream("new.bmp", FileMode.Create)
Dim encoder As New BmpBitmapEncoder()
Dim myTextBlock As New TextBlock()
myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString()
encoder.Frames.Add(BitmapFrame.Create(image))
encoder.Save(stream)

Anzeigen von Bildern in WPF

Es gibt mehrere Möglichkeiten, ein Bild in einer WPF-Anwendung (Windows Presentation Foundation) anzuzeigen. Bilder können mithilfe eines Image-Steuerelements angezeigt, in einem visuellen Element mithilfe eines ImageBrush-Objekts angemalt oder mithilfe eines ImageDrawing-Objekts gezeichnet werden.

Verwenden des Image-Steuerelements

Image ist ein Frameworkelement und der einfachste Weg zum Anzeigen von Bildern in Anwendungen. In XAML kann Image auf zwei Arten verwendet werden: mit Attributsyntax oder Eigenschaftensyntax. Im folgenden Beispiel wird veranschaulicht, wie ein Bild auf eine Breite von 200 Pixeln mit Attributsyntax und Eigenschaftensyntax gerendert wird. Weitere Informationen über Attributsyntax und Eigenschaftensyntax finden Sie unter Übersicht über Abhängigkeitseigenschaften.

<!-- Simple image rendering. However, rendering an image this way may not
     result in the best use of application memory. See markup below which
     creates the same end result but using less memory. -->
<Image Width="200" 
Source="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg"/>

<Image Width="200">
  <Image.Source>
    <!-- To save significant application memory, set the DecodePixelWidth or  
     DecodePixelHeight of the BitmapImage value of the image source to the desired 
     height and width of the rendered image. If you don't do this, the application will 
     cache the image as though it were rendered as its normal size rather than just 
     the size that is displayed. -->
    <!-- Note: In order to preserve aspect ratio, only set either DecodePixelWidth
         or DecodePixelHeight but not both. -->
    <BitmapImage DecodePixelWidth="200"  
     UriSource="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg" />
  </Image.Source>
</Image>

Viele der Beispiele verwenden ein BitmapImage-Objekt, um auf eine Bilddatei zu verweisen. BitmapImage ist eine spezialisierte BitmapSource, die für das Laden von XAML (Extensible Application Markup Language) optimiert ist. Sie stellt eine einfache Möglichkeit zum Anzeigen von Bildern als das Source-Objekt eines Image-Steuerelements dar.

Im folgenden Beispiel wird veranschaulicht, wie ein Bild mithilfe von Code auf eine Breite von 200 Pixel gerendert wird.

Hinweis

BitmapImage implementiert die ISupportInitialize-Schnittstelle, um die Initialisierung für mehrere Eigenschaften zu optimieren. Eigenschaftenänderungen können nur während der Objektinitialisierung erfolgen. Rufen Sie BeginInit auf, um zu signalisieren, dass die Initialisierung begonnen hat, und rufen Sie EndInit auf, um zu signalisieren, dass die Initialisierung abgeschlossen wurde. Nach der Initialisierung werden Eigenschaftenänderungen Eigenschaften ignoriert.

// Create Image Element
Image myImage = new Image();
myImage.Width = 200;

// Create source
BitmapImage myBitmapImage = new BitmapImage();

// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(@"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg");

// To save significant application memory, set the DecodePixelWidth or
// DecodePixelHeight of the BitmapImage value of the image source to the desired
// height or width of the rendered image. If you don't do this, the application will
// cache the image as though it were rendered as its normal size rather than just
// the size that is displayed.
// Note: In order to preserve aspect ratio, set DecodePixelWidth
// or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//set image source
myImage.Source = myBitmapImage;
' Create Image Element
Dim myImage As New Image()
myImage.Width = 200

' Create source
Dim myBitmapImage As New BitmapImage()

' BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit()
myBitmapImage.UriSource = New Uri("C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg")

' To save significant application memory, set the DecodePixelWidth or  
' DecodePixelHeight of the BitmapImage value of the image source to the desired 
' height or width of the rendered image. If you don't do this, the application will 
' cache the image as though it were rendered as its normal size rather than just 
' the size that is displayed.
' Note: In order to preserve aspect ratio, set DecodePixelWidth
' or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200
myBitmapImage.EndInit()
'set image source
myImage.Source = myBitmapImage

Drehen, Konvertieren und Zuschneiden von Bildern

WPF ermöglicht es Benutzern, Bilder mithilfe von Eigenschaften von BitmapImage oder mit zusätzlichen BitmapSource-Objekten, beispielsweise CroppedBitmap oder FormatConvertedBitmap, zu transformieren. Diese Bildtransformationen können Bilder skalieren oder drehen, das Pixelformat eines Bilds ändern oder ein Bild zuschneiden.

Bilddrehungen werden mithilfe der Rotation-Eigenschaft von BitmapImage ausgeführt. Drehungen können nur in 90-Grad-Schritten erfolgen. Im folgenden Beispiel wird ein Bild um 90 Grad gedreht.

<Image Width="150" Margin="5" Grid.Column="0" Grid.Row="1">
  <Image.Source>
    <TransformedBitmap Source="/sampleImages/watermelon.jpg" >
      <TransformedBitmap.Transform>
        <RotateTransform Angle="90"/>
      </TransformedBitmap.Transform>
    </TransformedBitmap>
  </Image.Source>
</Image>
// Create Image element.
Image rotated90 = new Image();
rotated90.Width = 150;

// Create the TransformedBitmap to use as the Image source.
TransformedBitmap tb = new TransformedBitmap();

// Create the source to use as the tb source.
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(@"sampleImages/watermelon.jpg", UriKind.RelativeOrAbsolute);
bi.EndInit();

// Properties must be set between BeginInit and EndInit calls.
tb.BeginInit();
tb.Source = bi;
// Set image rotation.
RotateTransform transform = new RotateTransform(90);
tb.Transform = transform;
tb.EndInit();
// Set the Image source.
rotated90.Source = tb;
' Create Image element.
Dim rotated90 As New Image()
rotated90.Width = 150

' Create the TransformedBitmap to use as the Image source.
Dim tb As New TransformedBitmap()

' Create the source to use as the tb source.
Dim bi As New BitmapImage()
bi.BeginInit()
bi.UriSource = New Uri("sampleImages/watermelon.jpg", UriKind.RelativeOrAbsolute)
bi.EndInit()

' Properties must be set between BeginInit and EndInit calls.
tb.BeginInit()
tb.Source = bi
' Set image rotation.
Dim transform As New RotateTransform(90)
tb.Transform = transform
tb.EndInit()
' Set the Image source.
rotated90.Source = tb

Die Konvertierung eines Bilds in ein anderes Pixelformat, so z. B. Graustufen, erfolgt mithilfe von FormatConvertedBitmap. In den folgenden Beispielen wird ein Bild in Gray4 konvertiert.

<!-- Grayscale XAML Image -->
<Image Width="200" Grid.Column="0" Grid.Row="1">
   <Image.Source>
      <FormatConvertedBitmap Source="/sampleImages/rocks.jpg"  DestinationFormat="Gray4" />
   </Image.Source>
</Image>
//Create Image Element
Image grayImage = new Image();
grayImage.Width = 200;
grayImage.Margin = new Thickness(5);

//Create source using xaml defined resource.
FormatConvertedBitmap fcb = new FormatConvertedBitmap(
   (BitmapImage)this.Resources["masterImage"],PixelFormats.Gray4,null,0);
//set image source
grayImage.Source = fcb;
'Create Image Element
Dim grayImage As New Image()
grayImage.Width = 200
grayImage.Margin = New Thickness(5)

'Create source using xaml defined resource.
Dim fcb As New FormatConvertedBitmap(CType(Me.Resources("masterImage"), BitmapImage), PixelFormats.Gray4, Nothing, 0)
'set image source
grayImage.Source = fcb

Um ein Bild zuzuschneiden, kann entweder die Clip-Eigenschaft von Image oder CroppedBitmap verwendet werden. Wenn Sie nur einen Teil eines Bilds anzeigen möchten, sollten Sie in der Regel Clip verwenden. Wenn Sie ein zugeschnittenes Bild codieren und speichern müssen, sollte die CroppedBitmap-Klasse verwendet werden. Im folgenden Beispiel wird ein Bild mithilfe der Clip-Eigenschaft über ein EllipseGeometry-Objekt zugeschnitten.

<!-- Cropping an Image using Clip -->
<Image Width="200" Grid.Column="0" Grid.Row="5" Margin="5"
   Source="/sampleImages/gecko.jpg">
  <Image.Clip>
    <EllipseGeometry Center="75,50" RadiusX="50" RadiusY="25" />
  </Image.Clip>
</Image>
//Create the image for clipping
Image clipImage = new Image();
clipImage.Width = 200;
clipImage.Margin = new Thickness(5);

//Create & Set source
BitmapImage bi = new BitmapImage();
//BitmapImage.UriSource must be in a BeginInit/EndInit block
bi.BeginInit();
bi.UriSource = new Uri("pack://application:,,/sampleImages/gecko.jpg");
bi.EndInit();
clipImage.Source = bi;

//Clip the using an EllipseGeometry
EllipseGeometry clipGeometry = new EllipseGeometry(new Point(75, 50), 50, 25);
clipImage.Clip = clipGeometry;
' Create the image for clipping
Dim clipImage As New Image()
clipImage.Width = 200
clipImage.Margin = New Thickness(5)

'Create & Set source
Dim bi As New BitmapImage()
' BitmapImage properties must be in a BeginInit/EndInit block
bi.BeginInit()
bi.UriSource = New Uri("pack://application:,,/sampleImages/gecko.jpg")
bi.EndInit()
clipImage.Source = bi

' Clip the using an EllipseGeometry
Dim clipGeometry As New EllipseGeometry(New System.Windows.Point(75, 50), 50, 25)
clipImage.Clip = clipGeometry

Dehnen von Bildern

Die Stretch-Eigenschaft steuert, wie ein Bild gedehnt wird, um seinen Container zu füllen. Die Stretch-Eigenschaft akzeptiert die folgenden Werte, die durch die Stretch-Enumeration definiert sind:

  • None: Das Bild wird nicht gedehnt, um den Ausgabebereich zu füllen. Wenn das Bild größer als der Ausgabebereich ist, wird das Bild in den Ausgabebereich gezogen, und alle überstehenden Bereiche werden abgeschnitten.

  • Fill: Das Bild wird skaliert, um in den Ausgabebereich zu passen. Da Höhe und Breite des Bilds unabhängig voneinander skaliert werden, wird das ursprüngliche Seitenverhältnis des Bilds möglicherweise nicht beibehalten. Dies bedeutet, dass das Bild möglicherweise verzerrt wird, um den Ausgabecontainer vollständig auszufüllen.

  • Uniform: Das Bild wird so skaliert, dass es vollständig im Ausgabebereich angezeigt wird. Das Seitenverhältnis des Inhalts wird beibehalten.

  • UniformToFill: Das Bild wird so skaliert, dass es den Ausgabebereich vollständig ausfüllt, und das ursprüngliche Seitenverhältnis des Bildes wird beibehalten.

Im folgenden Beispiel wird jede der verfügbaren Stretch-Enumerationen auf ein Image-Objekt angewendet.

Das folgende Bild zeigt die Ausgabe des Beispiels und veranschaulicht, wie sich die verschiedenen Stretch-Einstellungen auswirken, wenn sie auf ein Bild angewendet werden.

Different TileBrush Stretch settings
Unterschiedliche Dehneinstellungen

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <DockPanel>

    <Border DockPanel.Dock="Top" Background="Black">
      <TextBlock Foreground="White" HorizontalAlignment="Stretch" FontSize="20">
        Stretching an Image
      </TextBlock>
    </Border>

    <Grid Name="simpleGrid" Background="{StaticResource CheckeredBrushResource}" 
       Margin="10" 
       ShowGridLines="True"
       VerticalAlignment="Center"
       HorizontalAlignment="Center">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="175" />
        <ColumnDefinition Width="175" />
        <ColumnDefinition Width="175" />
        <ColumnDefinition Width="175" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="200"/>
      </Grid.RowDefinitions>
      <!-- Labels -->
      <TextBlock Style="{StaticResource Header1}" 
        Grid.Column="0" Grid.Row="0">None</TextBlock>
      <TextBlock Style="{StaticResource Header1}" 
        Grid.Column="1" Grid.Row="0">Uniform</TextBlock>
      <TextBlock Style="{StaticResource Header1}" 
        Grid.Column="2" Grid.Row="0">UniformToFill</TextBlock>
      <TextBlock Style="{StaticResource Header1}"
        Grid.Column="3" Grid.Row="0">Fill</TextBlock>
      <Border Grid.Column="0" Grid.Row="1" BorderThickness="1" BorderBrush="Black">
        <!-- None: Image is not scaled. If image is larger than the
             output area, the image will be cropped to the size of the output area.-->
        <Image
          Source="sampleImages/gecko.jpg" 
          Stretch="None" />
      </Border>
      <Border Grid.Column="1" Grid.Row="1" BorderThickness="1" BorderBrush="Black">
        <!-- Uniform: Scale to fit output area.
             Aspect ratio is preserved.-->
        <Image
          Source="sampleImages/gecko.jpg" 
          Stretch="Uniform" />
      </Border>
      <Border Grid.Column="2" Grid.Row="1" BorderThickness="1" BorderBrush="Black">
        <!-- UniformToFill: Scale to completely fill output area.
             Aspect ratio is preserved. Cropping may occur.-->
        <Image  
          Source="sampleImages/gecko.jpg" 
        Stretch="UniformToFill" />
      </Border>
      <Border Grid.Column="3" Grid.Row="1" BorderThickness="1" BorderBrush="Black">
      <!-- Fill: Scale to completely fill output area.
             Aspect ratio may not be preserved.-->
      <Image 
        Source="sampleImages/gecko.jpg" 
        Stretch="Fill" />
      </Border>
    </Grid>
  </DockPanel>
</Page>

Zeichnen mit Bildern

Bilder können auch in einer Anwendung angezeigt werden, indem sie mit einem Brush-Objekt ausgemalt werden. Mithilfe von Pinseln können Sie Benutzeroberflächenobjekte zeichnen, angefangen von einfachen Objekten, über Objekte in Volltonfarbe bis hin zu Objekten mit komplexen von Mustern und Bildern. Um mit Bildern auszumalen, verwenden Sie ein ImageBrush-Objekt. Ein ImageBrush-Objekt ist ein Typ von TileBrush, das seinen Inhalt als Bitmapbild definiert. Ein ImageBrush-Objekt zeigt ein einzelnes Bild an, das durch seine ImageSource-Eigenschaft angegeben ist. Sie können steuern, wie das Bild gedehnt, angeordnet und gekachelt wird. Auf diese Weise können Sie Zerrungen verhindern und Muster und andere Effekte herstellen. Die folgende Abbildung zeigt einige Effekte, die mit einem ImageBrush-Objekt erreicht werden können.

ImageBrush output examples
Bildpinsel können Formen, Steuerelemente, Text usw. füllen.

Im folgenden Beispiel wird veranschaulicht, wie ein Bild als Hintergrund einer Schaltfläche mit einem ImageBrush-Objekt gezeichnet wird.

<!-- Sets the button's Background property with an ImageBrush. The resulting
     button has an image as its background. -->
<Button Grid.Row="3" Grid.Column="2" 
 Height="75" Width="100" Foreground="White" FontWeight="Bold"
 HorizontalAlignment="Left">
  A Button
  <Button.Background>
    <ImageBrush ImageSource="sampleImages\blueberries.jpg" />
  </Button.Background>
</Button>

Weitere Informationen zu ImageBrush und dem Ausmalen (Zeichnen) von Bildern finden Sie unter Zeichnen mit Bildern, Zeichnungen und visuellen Elementen.

Bildmetadaten

Einige Bilddateien enthalten Metadaten, die den Inhalt oder die Eigenschaften der Datei beschreiben. Die meisten Digitalkameras erstellen z.B. Bilder, die Metadaten zum Fabrikat und Modell der Kamera enthalten, mit der das Bild aufgenommen wurde. Jedes Bildformat behandelt Metadaten unterschiedlich, aber WPF Imaging bietet eine einheitliche Möglichkeit zum Speichern und Abrufen von Metadaten für jedes unterstützte Bildformat.

Der Zugriff auf Metadaten wird durch die Metadata-Eigenschaft eines BitmapSource-Objekts bereitgestellt. Metadata gibt ein BitmapMetadata-Objekt zurück, das alle Metadaten umfasst, die im Bild enthalten sind. Diese Daten können in einem Metadatenschema oder einer Kombination aus unterschiedlichen Schemas vorliegen. WPF Imaging unterstützt die folgenden Bildmetadatenschemas: Exchangeable Image File Format (Exif), tEXt (PNG-Textdaten), Image File Directory (IFD), International Press Telecommunications Council (IPTC) und eXtensible Metadata Platform (XMP).

Um das Lesen von Metadaten zu vereinfachen, stellt BitmapMetadata mehrere benannte Eigenschaften bereit, auf die einfach zugegriffen werden kann, z. B. Author, Title und CameraModel. Viele dieser benannten Eigenschaften können auch verwendet werden, um Metadaten zu schreiben. Zusätzliche Unterstützung für das Lesen von Metadaten wird vom Metadaten-Abfragereader bereitgestellt. Die GetQuery-Methode wird zum Abrufen eines Metadaten-Abfragereaders verwendet, indem eine Zeichenfolgenabfrage, z. B. "/ app1/exif /" , bereitgestellt wird. Im folgenden Beispiel wird GetQuery verwendet, um den Text abzurufen, der im "/Text/Description" -Speicherort gespeichert ist.


// Add the metadata of the bitmap image to the text block.
TextBlock^ myTextBlock = gcnew TextBlock();
myTextBlock->Text = "The Description metadata of this image is: " + pngInplace->GetQuery("/Text/Description")->ToString();

// Add the metadata of the bitmap image to the text block.
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "The Description metadata of this image is: " + pngInplace.GetQuery("/Text/Description").ToString();
' Add the metadata of the bitmap image to the text block.
Dim myTextBlock As New TextBlock()
myTextBlock.Text = "The Description metadata of this image is: " + pngInplace.GetQuery("/Text/Description").ToString()

Zum Schreiben von Metadaten wird ein Metadaten-Abfragewriter verwendet. SetQuery ruft den Abfragegenerator (Abfragewriter) ab und legt den gewünschten Wert fest. Im folgenden Beispiel wird SetQuery verwendet, um den Text zu schreiben, der im "/Text/Description" -Speicherort gespeichert wird.

Stream^ pngStream = gcnew FileStream("smiley.png", FileMode::Open, FileAccess::ReadWrite, FileShare::ReadWrite);
PngBitmapDecoder^ pngDecoder = gcnew PngBitmapDecoder(pngStream, BitmapCreateOptions::PreservePixelFormat, BitmapCacheOption::Default);
BitmapFrame^ pngFrame = pngDecoder->Frames[0];
InPlaceBitmapMetadataWriter^ pngInplace = pngFrame->CreateInPlaceBitmapMetadataWriter();
if (pngInplace->TrySave() == true)
{
   pngInplace->SetQuery("/Text/Description", "Have a nice day.");
}
pngStream->Close();
Stream pngStream = new System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
PngBitmapDecoder pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapFrame pngFrame = pngDecoder.Frames[0];
InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();
if (pngInplace.TrySave() == true)
{ pngInplace.SetQuery("/Text/Description", "Have a nice day."); }
pngStream.Close();
Dim pngStream As New System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
Dim pngDecoder As New PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
Dim pngFrame As BitmapFrame = pngDecoder.Frames(0)
Dim pngInplace As InPlaceBitmapMetadataWriter = pngFrame.CreateInPlaceBitmapMetadataWriter()
If pngInplace.TrySave() = True Then
    pngInplace.SetQuery("/Text/Description", "Have a nice day.")
End If
pngStream.Close()

Code-Erweiterbarkeit

Ein Hauptmerkmal von WPF Imaging ist das Erweiterbarkeitsmodell für neue Bildcodecs. Diese nicht verwalteten Schnittstellen ermöglichen es Codec-Entwicklern, Codecs in WPF zu integrieren, sodass neue Bildformate automatisch von WPF-Anwendungen verwendet werden können.

Ein Beispiel für die Erweiterbarkeits-API finden Sie im Win32 Sample Codec. In diesem Beispiel wird veranschaulicht, wie ein Decoder und Encoder für ein benutzerdefiniertes Bildformat erstellt werden.

Hinweis

Der Codec muss digital signiert werden, damit das System ihn erkennt.

Weitere Informationen