Blog ENI : Toute la veille numérique !
Dernière chance (fin le 29/02) : -25€ dès 75€ sur les livres en ligne, vidéos... code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. WPF
  3. Graphisme en deux dimensions
Extrait - WPF Développez des applications structurées (MVVM, XAML...) (Nouvelle édition)
Extraits du livre
WPF Développez des applications structurées (MVVM, XAML...) (Nouvelle édition) Revenir à la page d'achat du livre

Graphisme en deux dimensions

Introduction

La technologie WPF est particulièrement adaptée au graphisme en deux dimensions. Ce type de développement était sans doute un des points faibles de Windows Forms (le constat est le même pour la triple dimension et pour l’animation graphique), ce qui explique probablement l’effort fourni par Microsoft sur ces aspects lors du passage vers WPF.

Premiers éléments du graphisme en WPF

1. Système de coordonnées

Le graphisme en deux dimensions dans WPF s’envisage au travers d’un système de coordonnées (X, Y) dans lequel Y représente la longueur à la bordure haute (Top) et X la longueur à la bordure gauche (Left). Ainsi, le coin supérieur gauche d’une fenêtre est au couple de coordonnées (0, 0).

Ainsi, deux structures sont utilisées par WPF pour afficher des objets graphiques exposés :

  • Point, qui correspond à un couple (X,Y). Il existe également une collection PointCollection qui regroupe un ensemble de points.

  • Rect, qui associe le point supérieur gauche d’un rectangle, une largeur (Width) et une hauteur (Height).

Ces deux structures ne sont pas directement manipulables mais sont impliquées dans bon nombre de définitions d’objets graphiques WPF.

2. Unité de longueur

Si on ne précise aucune unité, celle qui est utilisée par défaut est le DIP (Device-Independent Unit), qui est indépendant du système d’affichage (c’est-à-dire quelle que soit la densité de pixels par pouce de l’écran d’affichage). Pour rappel, un DIP correspond à 1/96 de pouce (2,54 cm).

96 DIP sont égales à 1 pouce.

Cela signifie donc que si la densité du périphérique est de 96 pixels par pouce, on aura une correspondance exacte entre DIP et pixel physique (1 DIP correspond à 1 pixel physique).

3. Catégorie d’objets Shape

WPF fournit une catégorie d’objets Shape. La classe abstraite Shape (voir ci-dessous) hérite de FrameworkElement. Plusieurs objets graphiques héritent de la classe Shape.


    public abstract class Shape : FrameworkElement 
    { 
        [CommonDependencyPropertyAttribute] 
        public static readonly DependencyProperty FillProperty; 
        public static readonly DependencyProperty StretchProperty; 
        public static readonly DependencyProperty StrokeDashArrayProperty; 
        public static readonly DependencyProperty StrokeDashCapProperty; 
        public static readonly DependencyProperty StrokeDashOffsetProperty; ...

Utilisation de la classe Drawing

1. Introduction

La classe Drawing permet d’afficher du contenu visuel et complexe. Son contenu peut être indifféremment une vidéo, une image vectorielle ou du texte stylisé.

Cette classe abstraite se définit ainsi :


    public abstract class Drawing : Animatable, IDrawingContent, 
IResource 
    { 
        public Rect Bounds { get; } 
        public Drawing Clone(); 
        public Drawing CloneCurrentValue(); 
    }
 

Les classes concrètes suivantes héritent de Drawing :

  • GeometryDrawing, qui permet de définir un dessin vectoriel.

  • ImageDrawing, qui permet de définir une image.

  • GlyphRunDrawing, qui permet de définir un visuel texte.

  • VideoDrawing, qui permet de diffuser un fichier vidéo (ou audio).

  • DrawingGroup, qui permet de réunir plusieurs objets de type Drawing. Par ailleurs, ce type fournit certaines fonctionnalités supplémentaires comme l’opacité (Opacity).

L’affichage d’un objet Drawing est conditionné par l’utilisation d’un objet DrawingImage ou DrawingBrush.

Attention à ne pas confondre ImageDrawing et DrawingImage. Le premier est un type de Drawing. Le second permet l’éventuel affichage du premier.

2. Exemple de GeometryDrawing

L’idée ici est de dessiner le bonhomme suivant en n’utilisant que des objets GeometryDrawing. En l’occurrence, on utilise des objets EllipseGeometry ainsi qu’un RectangleGeometry.

images/10EI10.PNG

MainWindow.xaml


<Window x:Class="CH10.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ 
presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:mc="http://schemas.openxmlformats.org/ 
markup-compatibility/2006" 
        xmlns:local="clr-namespace:CH10" 
        mc:Ignorable="d" 
        Title="ImageDrawing (bonhomme)" Height="400" Width="510"> 
    <StackPanel> ...

Aspects avancés du graphisme 2D

Plusieurs aspects sont particulièrement utiles notamment lors de l’utilisation de l’objet Drawing et n’ont pas été détaillés plus haut. C’est en particulier le cas des pinceaux (objet Brush).

1. Pinceaux

Les pinceaux servent à définir la texture et la nature des contours, en particulier lors de l’usage d’un objet Drawing. L’ensemble des pinceaux disponibles constituent des classes concrètes héritant de la classe abstraite Brush dont la description est ci-dessous :


    public abstract class Brush : Animatable, IFormattable, IResource 
    { 
        public static readonly DependencyProperty OpacityProperty; 
        public static readonly DependencyProperty RelativeTransformProperty; 
        public static readonly DependencyProperty TransformProperty; 
        protected Brush(); 
        public double Opacity { get; set; } 
        public Transform RelativeTransform { get; set; } 
        public Transform Transform { get; set; } 
        public Brush Clone(); 
        public Brush CloneCurrentValue(); 
        public override string ToString(); ...

Transformation en deux dimensions

1. Introduction

Une transformation permet d’appliquer une transformation au sens géométrique à une figure géométrique. Par exemple, pour afficher un triangle dont aucun côté ne serait parallèle aux bords de la fenêtre, il est aisé de dessiner un triangle simple puis de lui appliquer une transformation de type rotation pour obtenir le triangle désiré.

La transformation peut être définie de façon matricielle, grâce à l’objet MatrixTransform.

Plus simplement, on peut faire appel à un des objets suivants :

  • TranslateTransform, permet de réaliser une transformation de type translation.

  • RotateTransform, permet de réaliser une transformation de type rotation.

  • ScaleTransform, permet de réaliser une transformation de type homothétie.

  • SkewTransform, permet de réaliser une transformation qui correspond à une inclinaison de la figure géométrique.

  • TransformGroup, permet d’établir une combinaison de transformations.

2. Translation

On translate un carré de 100 selon l’axe X. Ci-dessous, le carré avant translation et le carré après.

images/10EI014.png

Cela s’obtient par le code suivant :


        <Rectangle Width="100" Height="100" Fill="LightGray"> 
        </Rectangle> 
         
        <Rectangle Width="100" Height="100" Fill="Gray"> 
            <Rectangle.RenderTransform> 
                <TranslateTransform X="100" /> 
            </Rectangle.RenderTransform> 
        </Rectangle> 
 

MainWindow.xaml


<Window x:Class="CH10.MainWindow" 
      ...