Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C# / .NET > La 2D en C# > Lecture du tutoriel

La 2D en C#

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : Artefact2
Note : 17 / 20 (3 votes)
Visualisations : 7 631

Plus d'informations Plus d'informations
Bonjour à vous. Dans ce mini-tuto, vous allez apprendre les bases du dessin en deux dimensions.

Dans beaucoup de projets, vous pourrez avoir besoin de disposer d'une surface sur laquelle vous pourrez dessiner (comme en C avec la SDL). Par exemple, lorsque vous créez un algorithme pour générer une fractale, ou encore un jeu en 2D, vous aurez nécessairement besoin de dessiner des objets (courbes, rectangles, ...) sur l'écran.

Le dessin en C# est d'une simplicité enfantine grâce aux classes .Net ; c'est un vrai délice et ce serait grandement dommage de nous en priver ! :pirate:

Attention : pour bien comprendre ce tuto, vous devez connaitre les bases des bases du C# et de la POO. Si vous ne comprenez pas les termes "Constructeur", "Méthode", "Objet", je vous conseille de lire le tuto sur C++, en particulier la partie sur la POO.
Sommaire du tutoriel :
Icône du chapitre

Les prérequis

Avant d'attaquer le vif du sujet, partons sur de bonne bases.

Notre projet initial



Tout d'abord, lancez votre IDE, si ce n'est déjà fait. J'utiliserai Visual Studio 2008, mais ne vous inquiétez pas, la procédure est identique pour Visual C#.

Nous allons créer un projet Windows Forms intitulé Dessin2D.

Vous devriez donc avoir un projet simple avec une fenêtre vide qui s'affiche.

Par mesure de simplicité et pour que ca soit plus pratique, nous allons insérer une PictureBox dans notre Form (Form est une classe générique représentant un formulaire, c'est à dire une fenêtre). Pour cela, double-cliquez sur l'élément "PictureBox" de la liste "Properties" (Propriétés en français). Il est inséré dans notre fenêtre.

Pourquoi c'est plus pratique d'utiliser une PictureBox ?

La PictureBox est une zone définie qui nous permet d'afficher une image. Cela nous permet donc d'afficher notre dessin dans la PictureBox et non directement dans la fenêtre.

Image utilisateur


Voila, nous en avons terminé avec le Concepteur Windows Forms. Attaquons le code :pirate:

Le code de mise en forme



Où est passé le code ? Je ne vois que la fenêtre...

Il suffit de faire un clic droit dans la zone vide près du formulaire et de choisir "Show Code" (afficher le code en français).

Image utilisateur


Le code du formulaire apparait donc. Il ressemble à ceci :
Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Dessin2D
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}


La méthode "Form1()" est le constructeur de notre formulaire. En .Net, chaque fenêtre est une classe qui hérite de la classe Form ! :magicien: La fonction "InitializeComponent()" permet d'initialiser le formulaire. Il ne faut pas y toucher.

Cependant, notre code ne nous permet pas encore de faire appel aux méthodes de dessin ! Nous devons ajouter la directive using suivante au début de notre code :
Code : C#
1
using System.Drawing.Drawing2D;


Ça y est, maintenant tout est prêt pour commencer ;)

Les classes Point et Rectangle



Rassurez vous, ces classes sont extrêmement faciles à utiliser. La classe Point représente un point dans le plan, représenté par ses coordonnées X et Y. Voici comment créer un point :
Code : C#
1
2
3
4
5
6
// Ce point représente l'origine du repère ; le repère est situé en haut à gauche de notre zone de dessin.
Point Origine = new Point(0, 0);
 
// On peut aussi créer un point totalement arbitraire ;
// Ce point est situé 157 pixels en dessous de l'origine, et 321 pixels à droite de l'origine.
Point UnPoint = new Point(157, 321);


Voici un petit schéma pour bien comprendre :
Image utilisateur


Un rectangle se définit par un point, son origine et une taille.
Code : C#
1
2
// Crée un rectangle d'origine Point1, de longueur Longueur et de largeur Largeur.
Rectangle rect = new Rectangle(Point1, new Size(Longueur, Largeur));


Bref ; c'est facile, on s'attarde pas dessus.

Maintenant, on ne rigole plus, on va attaquer le gros morceau :p

L'Objet Graphics

Notre classe qui va nous permettre de dessiner toute forme de choses est la classe Graphics.

Cette classe est très importante ; mais rassurez vous, elle est très facile à utiliser.

Comment instancier Graphics



Graphics est une classe particulière, dans le sens ou elle ne s'instancie pas directement. Par exemple, ce code fonctionnera pas :
Code : C#
1
Graphics g = new Graphics();


Vous obtiendrez une erreur "The type 'System.Drawing.Graphics' has no constructors defined", qui nous dit qu'on ne peut pas créer de Graphics avec l'élément new.

Vous avez compris : cette classe ne se crée pas, on obtient directement l'objet Graphics à partir d'un autre objet : c'est ce qui définit notre zone de dessin !

Par exemple, on peut obtenir le Graphics de notre PictureBox :
Code : C#
1
2
3
Graphics g = pictureBox1.CreateGraphics();
 
// Routines de dessin ici


Dans ce cas, l'origine (0, 0) est le coin supérieur gauche de notre PictureBox.

Cette méthode fonctionne, cependant je ne l'utilise pas. Elle produit souvent des résultats inattendus, par exemple notre fenêtre n'aimera pas du tout les redimensionnements, les déplacements, ... En effet, notre Graphics va dessiner directement dans la PictureBox, ce qui est risqué. En effet : le temps de tout dessiner, on ne sait pas ce qui peut arriver à notre fenêtre ! Elle peut avoir changé d'emplacement, de taille, ... Bref c'est compliqué.

Il y a une méthode beaucoup plus facile et sûre :
Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// On crée une nouvelle image bitmap, de la même taille que notre PictureBox
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
 
// Puis on récupère l'objet Graphics du bitmap :
Graphics g = Graphics.FromImage(bmp);
 
// Routines de dessin ici
 
// Puis on affiche notre image dans la PictureBox :
pictureBox1.Image = bmp;


Grâce à cette méthode, on passe par un Bitmap intermédiaire : on dessine tout dans notre Bitmap, bien au chaud, puis on affiche tout d'un coup, comme ça on est sûr que tout se passe bien !

De plus, cette méthode a un autre avantage : on peut sauvegarder l'image produite. Et la simplicité est enfantine, encore une fois !
Code : C#
1
2
// On enregistre notre Bitmap sur le disque dur
bmp.Save("ImageRendue.bmp");


Bon, maintenant que j'ai mon Graphics, j'en fais quoi ?


Pas de panique. Ça arrive. :p

Utilisation de votre objet Graphics



Reprenons notre code du début.

Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
 
namespace Dessin2D
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            // On veut que notre pictureBox remplisse toute la fenêtre ! (Fill = remplir)
            pictureBox1.Dock = DockStyle.Fill;
 
            // On veut que notre fenêtre ait une taille de 300*300 pixels.
            // On utilise le pointeur this qui correspond à notre fenêtre.
            this.Size = new Size(300, 300);
        }
    }
}


Nous avons plusieurs choses à faire : on doit faire un objet Graphics, une image Bitmap, et nos routines de dessin.

Ajoutons nos objets :

Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
 
namespace Dessin2D
{
    public partial class Form1 : Form
    {
        // Ces variables sont les données membres. Elles sont accessibles n'importe où dans la classe.
        private Graphics e;
        private Bitmap bmp;
 
        public Form1()
        {
            InitializeComponent();
 
            // On veut que notre pictureBox remplisse toute la fenêtre ! (Fill = remplir)
            pictureBox1.Dock = DockStyle.Fill;
 
            // On veut que notre fenêtre ait une taille de 300*300 pixels.
            // On utilise le pointeur this qui correspond à notre fenêtre.
            this.Size = new Size(300, 300);
 
            // On n'oublie pas d'initialiser nos variables !
            // Notre bitmap doit avoir la même taille que notre pictureBox
            bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            e = Graphics.FromImage(bmp);
        }
    }
}


Il ne nous reste plus maintenant qu'à ajouter notre routine de dessin.

Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
 
namespace Dessin2D
{
    public partial class Form1 : Form
    {
        // Ces variables sont les données membres. Elles sont accessibles n'importe où dans la classe.
        private Graphics e;
        private Bitmap bmp;
 
        public Form1()
        {
            InitializeComponent();
 
            // On veut que notre pictureBox remplisse toute la fenêtre ! (Fill = remplir)
            pictureBox1.Dock = DockStyle.Fill;
 
            // On veut que notre fenêtre ait une taille de 300*300 pixels.
            // On utilise le pointeur this qui correspond à notre fenêtre.
            this.Size = new Size(300, 300);
 
            // On n'oublie pas d'initialiser nos variables !
            // Notre bitmap doit avoir la même taille que notre pictureBox
            bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            e = Graphics.FromImage(bmp);
 
            // La fonction RoutineRendu() s'occupe du dessin.
            RoutineRendu();
        }
 
        // Cette fonction est une fonction membre privée.
        private void RoutineRendu()
        {
            // Nos routines de dessin viendront ici.
 
            // On affiche notre image Bitmap dans la PictureBox
            pictureBox1.Image = bmp;
        }
    }
}


Maintenant que tout est prêt, on peut attaquer les routines de dessin !

Routines de dessin



C'est ici que notre objet Graphics va déployer toute sa puissance.

Les formes géométriques simples



Pour dessiner des lignes, rectangles, ... Nous faisons appel aux fonctions membres de notre objet Graphics. Par exemple, le code suivant :
Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Par mesure de clarté, je ne représente que la fonction RoutineRendu() ici.
private void RoutineRendu()
{
    // Dessinons quelques lignes...
    e.DrawLine(new Pen(Color.Black), new Point(20, 20), new Point(20, 150));
    e.DrawLine(new Pen(Color.Red), new Point(20, 20), new Point(200, 20));
 
    // Dessinons un rectangle creux...
    e.DrawRectangle(new Pen(Color.Blue), new Rectangle(new Point(30, 30), new Size(100, 30)));
 
    // Et un rectangle plein :
    e.FillRectangle(new SolidBrush(Color.Turquoise), new Rectangle(new Point(40, 100), new Size(130, 100)));
 
    // On affiche notre image Bitmap dans la PictureBox
    pictureBox1.Image = bmp;
}

Produit le résultat suivant :
Image utilisateur


Je n'ai pas encore parlé des Brushs. Nous verrons cela en troisième partie. Retenez juste qu'il s'agit d'un pinceau pour dessiner, on peut le définir avec des couleurs, ...


Comme vous le voyez, tout cela est très facile, il faut juste bien maîtriser les coordonnées cartésiennes des points : l'axe Oy va vers le bas !

Des formes plus complexes



Vous vous servirez de ces trois méthodes 90% du temps, cependant il est toujours intéressant d'étudier le fonctionnement d'autres méthodes de dessin pour des formes plus complexes :
Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void RoutineRendu()
{
    // Essayons d'afficher du texte ! Attention :
    // Le constructeur de font exige une police de référence et une taille en flottant 
    // (RAPPEL : un nombre flottant s'écrit de la forme 1.15f).
    // PointF est une classe identique à Point mais utilise des flottants.
    e.DrawString("Salut les zéros !", new Font(FontFamily.GenericSansSerif, 20.00f), new SolidBrush(Color.BlueViolet), new PointF(10.00f, 10.00f));
 
    // On remplit une éllipse (un cercle aplati)...
    e.FillEllipse(new SolidBrush(Color.Chocolate), new Rectangle(new Point(30, 60), new Size(250, 50)));
 
    // On fait un tableau de "Point" contenant les sommets de notre nouveau polygone.
    Point[] Sommets = new Point[4];
    Sommets[0] = new Point(30, 110);
    Sommets[1] = new Point(200, 150);
    Sommets[2] = new Point(280, 210);
    Sommets[3] = new Point(10, 250);
 
    // Puis on le dessine.
    e.FillPolygon(new SolidBrush(Color.Aqua), Sommets);
 
    // On affiche notre image Bitmap dans la PictureBox
    pictureBox1.Image = bmp;
}

Donne comme résultat :
Image utilisateur


Pour terminer



Maintenant, les routines de dessin n'ont plus aucun secret pour vous. Il ne nous reste plus qu'à voir les Brushs et les Textures.

Les Brush

Les Brushes sont des classes nécessaires pour dessiner en 2D. Il y a trois types de Brushes : les Pen, les TextureBrush et les SolidBrush.

Un crayon simple : la classe Pen



La classe Pen représente un crayon. Le constructeur est très simple :
Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private void RoutineRendu()
{
    // On fait des tests avec différents constructeurs de Pen...
    Pen pen = new Pen(Color.Blue, 10.0f);
    e.DrawLine(pen, new Point(0, 0), new Point(100, 100));
 
    // On change l'épaisseur
    pen = new Pen(Color.Red, 3.0f);
    e.DrawLine(pen, new Point(50, 0), new Point(150, 100));
 
    // Ici, on n'indique pas d'épaisseur : l'épaisseur par défaut (1.0f) est donc utilisée.
    pen = new Pen(Color.Green);
    e.DrawLine(pen, new Point(0, 50), new Point(100, 150));
 
    // On affiche notre image Bitmap dans la PictureBox
    pictureBox1.Image = bmp;
}


Voici les différents résultats obtenus :
Image utilisateur


La classe Pen est utilisée pour les dessins de traits.
Il existe aussi un constructeur prenant un Brush en paramètre, je vous laisse essayer ;)


Les différents types de Brush



La classe Brush représente un pinceau. Vous devriez déjà connaître les brushs si vous utilisez un logiciel de retouche d'image, par exemple Photoshop ou GIMP. Ici, la classe Brush est une pseudo-classe : on ne peut l'instancier mais elle possède beaucoup de classes filles (qui héritent de Brush).

Les SolidBrush



Les brushs que vous utilisez le plus souvent sont les SolidBrush. Leur fonctionnement est identique à un Pen, ce brush se construit à partir d'une couleur et représente un pinceau de cette couleur. Les images parlent mieux que les mots, je vous laisse regarder le code et le résultat :

Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
private void RoutineRendu()
{
    // On crée différents brushs
    SolidBrush sb1 = new SolidBrush(Color.White);
    SolidBrush sb2 = new SolidBrush(Color.SkyBlue);
 
    // Puis on les utilise !
    e.FillEllipse(sb1, new Rectangle(new Point(10, 10), new Size(200, 200)));
    e.FillEllipse(sb2, new Rectangle(new Point(50, 50), new Size(100, 100)));
 
    // Plûtot que de créer un brush dans une variable, on peut également contracter les deux instructions :
    e.FillEllipse(new SolidBrush(Color.Black), new Rectangle(new Point(70, 70), new Size(20, 20)));
 
    // On affiche notre image Bitmap dans la PictureBox
    pictureBox1.Image = bmp;
}


Cela produit le résultat suivant :
Image utilisateur


Les TextureBrush



Ces Brush s'utilisent de la même manière que les SolidBrush, mais on les construit avec un objet Image à la place d'une couleur.

Code : C#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Cette fonction est une fonction membre privée.
private void RoutineRendu()
{
    // On crée notre TextureBrush à partir d'une texture sur le disque dur
    Bitmap image = new Bitmap("D:\\Degrade.png");
    TextureBrush tb = new TextureBrush(image);
 
    // Soyons fous, remplissons toute la fenêtre !
    e.FillRectangle(tb, new Rectangle(new Point(0, 0), new Size(pictureBox1.Width, pictureBox1.Height)));
 
    // On affiche notre image Bitmap dans la PictureBox
    pictureBox1.Image = bmp;
}


Ce brush nous produit le résultat suivant :
Image utilisateur


Mon image D:\Degrade.png contenait évidemment un dégradé orange-rouge :p


C'est fini, rangez vos pots de peinture et vos pinceaux ! Vous en avez assez appris. :D

C'est fini ! Vous maitrisez maintenant parfaitement le dessin 2D en C#.Net, et vous êtes toujours vivants !

Vous voulez en savoir plus ? Consultez la documentation MSDN, cette page est un bon point de départ.

Ce que j'ai voulu avant tout vous faire voir, c'est la magie de .Net : quoi qu'on veuille faire, on dispose de tout. Toutes les classes sont unies et cohérentes... Vous avez besoin de quelque chose ? Une petite recherche dans l'aide et hop, on a trouvé. Beaucoup de gens me disent que C#.Net n'a pas d'avenir, mais je pense qu'au contraire il se répand très vite.

Grâce à ce que vous venez d'apprendre, vous pouvez faire :


J'espère que ce tuto vous a plu, si vos commentaires sont positifs, j'en rédigerai peut-être d'autres... Qui sait ? ;)
Retour en haut Retour en haut


Créé : le 11/03/2008 à 20:49:31
Modifié : le 22/08/2008 à 16:07:32
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 100 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.063s (0.0534s)