Partager via


Peinture avec des objets d'image, de dessin et visuels

Mise à jour : novembre 2007

Cette rubrique explique comment utiliser les objets ImageBrush, DrawingBrushVisualBrush pour peindre une zone avec une image, un Drawing ou un Visual.

Cette rubrique comprend les sections suivantes.

  • Composants requis
  • Peindre une zone avec une image
  • Exemple : peindre un objet avec une image bitmap
  • Peindre une zone avec un dessin (Drawing)
  • Exemple : peindre un objet avec un dessin
  • Peindre une zone avec un visuel
  • Exemple : peindre un objet avec un visuel
  • Exemple : créer une réflexion
  • Fonctionnalités TileBrush
  • Rubriques connexes

Composants requis

Pour comprendre cette rubrique, vous devez être familiarisé avec les différents types de pinceaux que propose Windows Presentation Foundation (WPF) et leurs fonctionnalités de base. Pour une introduction, consultez Vue d'ensemble des pinceaux WPF.

Peindre une zone avec une image

Un ImageBrush peint une zone avec une ImageSource. Le type d'ImageSource le plus courant à utiliser avec un ImageBrush est une BitmapImage, qui décrit un graphique bitmap. Vous pouvez utiliser une DrawingImage pour peindre à l'aide d'un objet Drawing, mais il est plus simple d'utiliser un DrawingBrush. Pour plus d'informations sur les objets ImageSource, consultez Vue d'ensemble de l'acquisition d'images.

Pour peindre avec un ImageBrush, créez une BitmapImage et utilisez-la pour charger un contenu de bitmap. Ensuite, utilisez BitmapImage pour définir la propriété ImageSource du ImageBrush. Enfin, appliquez le ImageBrush à l'objet que vous voulez peindre. En XAML (Extensible Application Markup Language), vous pouvez également définir la propriété ImageSource du ImageBrush selon le chemin d'accès de l'image à charger. 

Comme tous les objets Brush, un ImageBrush peut être utilisé pour peindre des objets tels que des formes, des panneaux, des contrôles et du texte. L'illustration suivante indique divers effets pouvant être accomplis avec un ImageBrush.

Objets peints avec un ImageBrush

Exemples de sortie ImageBrush

Par défaut, un ImageBrush étend son image de façon à remplir complètement la zone qui est peinte, en déformant peut-être l'image si la zone peinte a des proportions différentes de celles de l'image. Vous pouvez modifier ce comportement en faisant passer la propriété Stretch de la valeur par défaut Fill à None, Uniform ou UniformToFill. Dans la mesure où ImageBrush est un type de TileBrush, vous pouvez spécifier exactement comment un pinceau image remplit la zone de sortie et même crée des motifs. Pour plus d'informations sur le blocage et les fonctionnalités avancées de TileBrush, consultez Vue d'ensemble de TileBrush.

Exemple : peindre un objet avec une image bitmap

L'exemple suivant utilise un ImageBrush pour peindre l'objet Background d'un Canvas.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.Samples.BrushExamples.ImageBrushExample"
  WindowTitle="ImageBrush Example"
  Background="White">

  <StackPanel>

    <Canvas
      Height="200" Width="300">
      <Canvas.Background>
        <ImageBrush ImageSource="sampleImages\Waterlilies.jpg" />
      </Canvas.Background>
    </Canvas>


  </StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Microsoft.Samples.BrushExamples
{

    public class ImageBrushExample : Page
    {

        public ImageBrushExample()
        {

            StackPanel mainPanel = new StackPanel();
            canvasBackgroundExample(mainPanel);
            this.Content = mainPanel;

        }


        private void canvasBackgroundExample(Panel mainPanel)
        {

            BitmapImage theImage = new BitmapImage
                (new Uri("sampleImages\\Waterlilies.jpg", UriKind.Relative));

            ImageBrush myImageBrush = new ImageBrush(theImage);

            Canvas myCanvas = new Canvas();
            myCanvas.Width = 300;
            myCanvas.Height = 200;
            myCanvas.Background = myImageBrush;

            mainPanel.Children.Add(myCanvas);


        }

    }

}

Peindre une zone avec un dessin (Drawing)

Un DrawingBrush vous permet de peindre une zone avec des formes, du texte, des images et de la vidéo. Les formes à l'intérieur d'un pinceau de dessin peuvent elles-mêmes être peintes avec des couleurs unies, des dégradées, des images et même un DrawingBrush. L'illustration suivante montre certaines utilisations d'un DrawingBrush.

Objets peints par un DrawingBrush

Exemples de sortie DrawingBrush

Un DrawingBrush peint une zone avec un objet Drawing. Un objet Drawing décrit un contenu visible, tel qu'une forme, une image, une vidéo ou une ligne de texte. Il existe différents types d'objets Drawing pour les types différents de contenu. La liste qui suit répertorie les différents types d'objets Drawing.

Pour plus d'informations sur les objets Drawing, consultez Vue d'ensemble des objets Drawing.

À l'instar d'un ImageBrush, un DrawingBrush étend son Drawing pour remplir sa zone de sortie. Vous pouvez substituer ce comportement en modifiant la valeur par défaut Fill de la propriété Stretch. Pour plus d'informations, consultez la propriété Stretch.

Exemple : peindre un objet avec un dessin

L'exemple suivant montre comment peindre un objet avec un dessin de trois ellipses. Un GeometryDrawing permet de décrire les ellipses.

<Button Content="A Button">
  <Button.Background>
    <DrawingBrush>
      <DrawingBrush.Drawing>
        <GeometryDrawing Brush="LightBlue">
          <GeometryDrawing.Geometry>
            <GeometryGroup>
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="25,50" />
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="50,50" />
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="75,50" />
            </GeometryGroup>
          </GeometryDrawing.Geometry>
          <GeometryDrawing.Pen>
            <Pen Thickness="1" Brush="Gray" />
          </GeometryDrawing.Pen>
        </GeometryDrawing>
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Button.Background>
</Button>
// Create a DrawingBrush.
DrawingBrush myDrawingBrush = new DrawingBrush();

// Create a drawing.
GeometryDrawing myGeometryDrawing = new GeometryDrawing();
myGeometryDrawing.Brush = Brushes.LightBlue;
myGeometryDrawing.Pen = new Pen(Brushes.Gray, 1);
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(new EllipseGeometry(new Point(25,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(50,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(75,50), 12.5, 25));

myGeometryDrawing.Geometry = ellipses;
myDrawingBrush.Drawing = myGeometryDrawing;

Button myButton = new Button();
myButton.Content = "A Button";

// Use the DrawingBrush to paint the button's background.
myButton.Background = myDrawingBrush;

Peindre une zone avec un visuel

Le plus puissant et le plus polyvalent de tous les pinceaux, le VisualBrush peint une zone avec un Visual. Un Visual est un type graphique de bas niveau qui sert d'ancêtre à de nombreux composants graphiques. Par exemple, les classes Window, FrameworkElement et Control correspondent à tous les types d'objets Visual. En utilisant un VisualBrush, vous pouvez peindre des zones avec n'importe quel objet graphique Windows Presentation Foundation (WPF) ou presque.

Remarque :

Bien que VisualBrush soit un type d'objet Freezable, il ne peut pas être gelé (mis dans un état en lecture seule) quand sa propriété Visual a une valeur autre que null.

Il existe deux façons de spécifier le contenu Visual d'un VisualBrush.

  • Créez un nouveau Visual, puis utilisez-le pour définir la propriété Visual du VisualBrush. Pour obtenir un exemple, consultez la section Exemple : peindre un objet avec un visuel qui suit.

  • Utilisez un Visual existant, qui crée une image dupliquée de la cible Visual. Vous pouvez alors utiliser VisualBrush pour créer des effets intéressants, comme la réflexion et l'agrandissement. Pour obtenir un exemple, consultez la section Comment créer une vue sous Exemple : créer une réflexion.

Lorsque vous définissez un nouveau Visual pour un VisualBrush et que Visual est un UIElement (un panneau ou un contrôle), le système de disposition s'exécute sur UIElement et ses éléments enfants quand la propriété AutoLayoutContent a la valeur true. Cependant, la racine UIElement est essentiellement isolée du reste du système : les styles et la disposition externe ne peuvent pas franchir cette limite. Par conséquent, vous devez explicitement spécifier la taille de la racine UIElement, car son seul parent est le VisualBrush et ne peut donc pas se dimensionner automatiquement à la zone qui est peinte. Pour plus d'informations sur la disposition dans Windows Presentation Foundation (WPF), consultez Système de disposition.

À l'instar de ImageBrush et de DrawingBrush, un VisualBrush étend son contenu pour remplir sa zone de sortie. Vous pouvez substituer ce comportement en modifiant la valeur par défaut Fill de la propriété Stretch. Pour plus d'informations, consultez la propriété Stretch.

Exemple : peindre un objet avec un visuel

Dans l'exemple suivant, plusieurs contrôles et un panneau sont utilisés pour peindre un rectangle.

<Rectangle Width="150" Height="150" Stroke="Black" Margin="5,0,5,0">
  <Rectangle.Fill>
    <VisualBrush>
      <VisualBrush.Visual>
        <StackPanel Background="White">
          <Rectangle Width="25" Height="25" Fill="Red" Margin="2" />
          <TextBlock FontSize="10pt" Margin="2">Hello, World!</TextBlock>
          <Button Margin="2">A Button</Button>
        </StackPanel>
      </VisualBrush.Visual>
    </VisualBrush>
  </Rectangle.Fill>
</Rectangle>
VisualBrush myVisualBrush = new VisualBrush();

// Create the visual brush's contents.
StackPanel myStackPanel = new StackPanel();
myStackPanel.Background = Brushes.White;

Rectangle redRectangle = new Rectangle();
redRectangle.Width = 25;
redRectangle.Height =25; 
redRectangle.Fill = Brushes.Red;
redRectangle.Margin = new Thickness(2);
myStackPanel.Children.Add(redRectangle);

TextBlock someText = new TextBlock();
FontSizeConverter myFontSizeConverter = new FontSizeConverter();
someText.FontSize = (double)myFontSizeConverter.ConvertFrom("10pt");
someText.Text = "Hello, World!";
someText.Margin = new Thickness(2);
myStackPanel.Children.Add(someText);

Button aButton = new Button();
aButton.Content = "A Button";
aButton.Margin = new Thickness(2);
myStackPanel.Children.Add(aButton);

// Use myStackPanel as myVisualBrush's content.
myVisualBrush.Visual = myStackPanel;

// Create a rectangle to paint.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 150;
myRectangle.Height = 150;
myRectangle.Stroke = Brushes.Black;
myRectangle.Margin = new Thickness(5,0,5,0);

// Use myVisualBrush to paint myRectangle.
myRectangle.Fill = myVisualBrush;

Exemple : créer une réflexion

L'exemple précédent a montré comment créer un nouveau Visual à utiliser comme arrière-plan. Vous pouvez également utiliser un VisualBrush pour afficher un effet visuel existant ; cette fonction vous permet de produire des effets visuels intéressants, tels que des réflexions et des agrandissements. L'exemple suivant utilise un VisualBrush pour créer la réflexion d'une Border qui contient plusieurs éléments. L'illustration suivante montre la sortie produite par cet exemple.

Objet visuel réfléchi

Objet Visual réfléchi

using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.IO;
using System.Collections.ObjectModel;
using System.Windows.Shapes;
namespace SDKSample
{
    public partial class ReflectionExample : Page
    {
        public ReflectionExample()
        {
            // Create a name scope for the page.
            NameScope.SetNameScope(this, new NameScope());

            this.Background = Brushes.Black;
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(50);

            Border myReflectedBorder = new Border();
            this.RegisterName("ReflectedVisual", myReflectedBorder);

            // Create a gradient background for the border.
            GradientStop firstStop = new GradientStop();
            firstStop.Offset = 0.0;
            Color firstStopColor = new Color();
            firstStopColor.R = 204;
            firstStopColor.G = 204;
            firstStopColor.B = 255;
            firstStopColor.A = 255;
            firstStop.Color = firstStopColor;
            GradientStop secondStop = new GradientStop();
            secondStop.Offset = 1.0;
            secondStop.Color = Colors.White;

            GradientStopCollection myGradientStopCollection = new GradientStopCollection();
            myGradientStopCollection.Add(firstStop);
            myGradientStopCollection.Add(secondStop);

            LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();
            myLinearGradientBrush.StartPoint = new Point(0, 0.5);
            myLinearGradientBrush.EndPoint = new Point(1, 0.5);
            myLinearGradientBrush.GradientStops = myGradientStopCollection;

            myReflectedBorder.Background = myLinearGradientBrush;

            // Add contents to the border.
            StackPanel borderStackPanel = new StackPanel();
            borderStackPanel.Orientation = Orientation.Horizontal;
            borderStackPanel.Margin = new Thickness(10);

            TextBlock myTextBlock = new TextBlock();
            myTextBlock.TextWrapping = TextWrapping.Wrap;
            myTextBlock.Width = 200;
            myTextBlock.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit." +
                               " Suspendisse vel ante. Donec luctus tortor sit amet est." +
                               " Nullam pulvinar odio et wisi." +
                               " Pellentesque quis magna. Sed pellentesque." +
                               " Nulla euismod." +
                               "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.";

            borderStackPanel.Children.Add(myTextBlock);

            StackPanel ellipseStackPanel = new StackPanel();

            Ellipse ellipse1 = new Ellipse();
            ellipse1.Margin = new Thickness(10);
            ellipse1.Height = 50;
            ellipse1.Width = 50;
            ellipse1.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse1);
            Ellipse ellipse2 = new Ellipse();
            ellipse2.Margin = new Thickness(10);
            ellipse2.Height = 50;
            ellipse2.Width = 50;
            ellipse2.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse2);
            Ellipse ellipse3 = new Ellipse();
            ellipse3.Margin = new Thickness(10);
            ellipse3.Height = 50;
            ellipse3.Width = 50;
            ellipse3.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse3);
            borderStackPanel.Children.Add(ellipseStackPanel);

            myReflectedBorder.Child = borderStackPanel;

            // Create divider rectangle
            Rectangle dividerRectangle = new Rectangle();
            dividerRectangle.Height = 1;
            dividerRectangle.Fill = Brushes.Gray;
            dividerRectangle.HorizontalAlignment = HorizontalAlignment.Stretch;

            // Create the object to contain the reflection.
            Rectangle reflectionRectangle = new Rectangle();

            // Bind the height of the rectangle to the border height.
            Binding heightBinding = new Binding();
            heightBinding.ElementName = "ReflectedVisual";
            heightBinding.Path = new PropertyPath(Rectangle.HeightProperty);
            BindingOperations.SetBinding(reflectionRectangle, Rectangle.HeightProperty, heightBinding);

            // Bind the width of the rectangle to the border width.
            Binding widthBinding = new Binding();
            widthBinding.ElementName = "ReflectedVisual";
            widthBinding.Path = new PropertyPath(Rectangle.WidthProperty);
            BindingOperations.SetBinding(reflectionRectangle, Rectangle.WidthProperty, widthBinding);

            // Creates the reflection.
            VisualBrush myVisualBrush = new VisualBrush();
            myVisualBrush.Opacity = 0.75;
            myVisualBrush.Stretch = Stretch.None;
            Binding reflectionBinding = new Binding();
            reflectionBinding.ElementName = "ReflectedVisual";
            BindingOperations.SetBinding(myVisualBrush, VisualBrush.VisualProperty, reflectionBinding);

            ScaleTransform myScaleTransform = new ScaleTransform();
            myScaleTransform.ScaleX = 1;
            myScaleTransform.ScaleY = -1;
            TranslateTransform myTranslateTransform = new TranslateTransform();
            myTranslateTransform.Y = 1;

            TransformGroup myTransformGroup = new TransformGroup();
            myTransformGroup.Children.Add(myScaleTransform);
            myTransformGroup.Children.Add(myTranslateTransform);

            myVisualBrush.RelativeTransform = myTransformGroup;

            reflectionRectangle.Fill = myVisualBrush;

            // Create a gradient background for the border.
            GradientStop firstStop2 = new GradientStop();
            firstStop2.Offset = 0.0;
            Color c1 = new Color();
            c1.R = 0;
            c1.G = 0;
            c1.B = 0;
            c1.A = 255;
            firstStop2.Color = c1;
            GradientStop secondStop2 = new GradientStop();
            secondStop2.Offset = 0.5;
            Color c2 = new Color();
            c2.R = 0;
            c2.G = 0;
            c2.B = 0;
            c2.A = 51;
            firstStop2.Color = c2;
            GradientStop thirdStop = new GradientStop();
            thirdStop.Offset = 0.75;
            Color c3 = new Color();
            c3.R = 0;
            c3.G = 0;
            c3.B = 0;
            c3.A = 0;
            thirdStop.Color = c3;

            GradientStopCollection myGradientStopCollection2 = new GradientStopCollection();
            myGradientStopCollection2.Add(firstStop2);
            myGradientStopCollection2.Add(secondStop2);
            myGradientStopCollection2.Add(thirdStop);

            LinearGradientBrush myLinearGradientBrush2 = new LinearGradientBrush();
            myLinearGradientBrush2.StartPoint = new Point(0.5, 0);
            myLinearGradientBrush2.EndPoint = new Point(0.5, 1);
            myLinearGradientBrush2.GradientStops = myGradientStopCollection2;

            reflectionRectangle.OpacityMask = myLinearGradientBrush2;

            BlurBitmapEffect myBlurBitmapEffect = new BlurBitmapEffect();
            myBlurBitmapEffect.Radius = 1.5;

            reflectionRectangle.BitmapEffect = myBlurBitmapEffect;

            myStackPanel.Children.Add(myReflectedBorder);
            myStackPanel.Children.Add(dividerRectangle);
            myStackPanel.Children.Add(reflectionRectangle);
            this.Content = myStackPanel;

        }
        /*
    <Rectangle 
      Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}" 
      Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">

      <Rectangle.OpacityMask>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
          <GradientStop Color="#FF000000" Offset="0.0" />
          <GradientStop Color="#33000000" Offset="0.5" />
          <GradientStop Color="#00000000" Offset="0.75" />
        </LinearGradientBrush>
      </Rectangle.OpacityMask>

      <Rectangle.BitmapEffect>
        <BlurBitmapEffect Radius="1.5" />
      </Rectangle.BitmapEffect>

    </Rectangle>
  </StackPanel>
</Page>

*/

    }
}
<Page  
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  Background="Black">


  <StackPanel Margin="50">

    <!-- The object to reflect. -->
    <Border Name="ReflectedVisual" Width="400">
      <Border.Background>
        <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
          <GradientStop Offset="0.0" Color="#CCCCFF" />
          <GradientStop Offset="1.0" Color="White" />
        </LinearGradientBrush>
      </Border.Background>
      <StackPanel Orientation="Horizontal" Margin="10">        
        <TextBlock TextWrapping="Wrap" Width="200" Margin="10">
          Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
          Suspendisse vel ante. Donec luctus tortor sit amet est.
          Nullam pulvinar odio et wisi.
          Pellentesque quis magna. Sed pellentesque.
          Nulla euismod.
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
        </TextBlock>
        <StackPanel>
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
        </StackPanel>
      </StackPanel>
    </Border>

    <Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch" />

    <!-- The object to contain the reflection.-->
    <Rectangle 
      Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}" 
      Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">
      <Rectangle.Fill>

        <!-- Creates the reflection. -->
        <VisualBrush 
          Opacity="0.75" Stretch="None"
          Visual="{Binding ElementName=ReflectedVisual}">
          <VisualBrush.RelativeTransform>

            <!-- Flip the reflection. -->
            <TransformGroup>
              <ScaleTransform ScaleX="1" ScaleY="-1" />
              <TranslateTransform  Y="1" />
            </TransformGroup>
          </VisualBrush.RelativeTransform>
        </VisualBrush>
      </Rectangle.Fill>

      <Rectangle.OpacityMask>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
          <GradientStop Color="#FF000000" Offset="0.0" />
          <GradientStop Color="#33000000" Offset="0.5" />
          <GradientStop Color="#00000000" Offset="0.75" />
        </LinearGradientBrush>
      </Rectangle.OpacityMask>

      <Rectangle.BitmapEffect>
        <BlurBitmapEffect Radius="1.5" />
      </Rectangle.BitmapEffect>

    </Rectangle>
  </StackPanel>
</Page>

Pour d'autres exemples qui montrent comment agrandir des zones de l'écran et créer des réflexions, consultez VisualBrush, exemple.

Fonctionnalités TileBrush

ImageBrush, DrawingBrush et VisualBrush sont des types d'objets TileBrush. Les objets TileBrush vous offrent un contrôle énorme sur la façon dont une zone est peinte avec une image, un dessin ou un visuel. Par exemple, au lieu de simplement peindre une zone à l'aide d'une seule image étendue, vous pouvez utiliser une série de mosaïques d'images qui créent un motif.

Un TileBrush a trois composants essentiels : un content, des titres et la zone de sortie.

Composants d'un TileBrush avec une seule mosaïque

Composants de TileBrush

Composants d'un TileBrush avec plusieurs mosaïques

Composants d'un TileBrush en mosaïque

Pour plus d'informations sur les fonctions de disposition en mosaïque TileBrush, consultez Vue d'ensemble de TileBrush.

Voir aussi

Tâches

ImageBrush, exemple

DrawingBrush, exemple

VisualBrush, exemple

Concepts

Vue d'ensemble de TileBrush

Vue d'ensemble des pinceaux WPF

Vue d'ensemble de l'acquisition d'images

Vue d'ensemble des objets Drawing

Vue d'ensemble des masques d'opacité

Vue d'ensemble du rendu graphique de Windows Presentation Foundation

Référence

ImageBrush

DrawingBrush

VisualBrush

TileBrush