API - Chapitre 03.pdf - IUT d'Arles
API - Chapitre 03.pdf - IUT d'Arles
API - Chapitre 03.pdf - IUT d'Arles
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
3. Affichage graphique<br />
3.1 Graphics Device Interface (GDI)<br />
Le GDI (Graphics Device Interface) est un ensemble de fonctions de<br />
l’<strong>API</strong> Windows permettant de dessiner à l’écran, en mémoire ou sur<br />
imprimante.<br />
Ces fonctions permettent le tracé de primitives graphiques (points,<br />
lignes, rectangles, cercles, …), d’images bitmap ou encore de texte.<br />
Le GDI fonctionne autour du principe de « Device Context » (DC),<br />
représenté par le type HDC (« Handle to Device Context »).<br />
1
Un HDC désigne un endroit sur lequel on peut dessiner : l’écran<br />
tout entier, une fenêtre toute entière, la zone client d’une fenêtre, une<br />
image stockée en mémoire ou une imprimante.<br />
Pour afficher sur un périphérique à sortie graphique, il faut toujours<br />
avoir un DC lié à celui-ci.<br />
En donnant un handle sur ce DC à une fonction GDI on indique à<br />
Windows sur quel périphérique de sortie on souhaite travailler.<br />
indépendance vis à vis du matériel. On utilise le même code pour<br />
dessiner à l’écran ou sur une imprimante.<br />
2
Le cas le plus courant d’affichage se fait dans la zone client de la<br />
fenêtre.<br />
Y<br />
mini<br />
X<br />
mini<br />
Y maxi<br />
= zone<br />
client<br />
X maxi<br />
3
Système de coordonnées<br />
GDI trace les primitives graphiques (points, lignes,<br />
rectangles, etc.), les images, le texte, dans un<br />
système de coordonnées.<br />
Un moniteur réalise l’affichage sur une matrice<br />
rectangulaire de points appelés pixels .<br />
Les algorithmes de tracés de figure de GDI<br />
permettent de donner une couleur à certains de ces<br />
pixels (ici pour tracer une ligne).<br />
4
3.2 Evolution de GDI : GDI+<br />
Nombreuses innovations :<br />
Chargement d’images (BMP, JPG, TIFF, PNG, GIF, ICO, …)<br />
Nouvelles primitives graphiques (courbes, …)<br />
Nouveaux types de tracés (flèche, …)<br />
Transformations (rotations, symétries, …)<br />
Ajustements (contraste, luminosité, netteté, …)<br />
…<br />
La plupart des méthodes de GDI+ sont surchargées : nombreuses<br />
syntaxes différentes.<br />
Plus d’infos sur le MSDN (MicroSoft Developper Network) :<br />
msdn.microsoft.com/<br />
5
3.2.1 Configuration<br />
Fichiers nécessaires :<br />
gdiplus.dll : La DLL<br />
gdiplus.lib : La librairie<br />
gdiplus*.h : Les fichiers d’en-tête<br />
Le VC++ doit être configuré de manière à connaître le chemin des<br />
fichiers d’include et de librairies de GDI+ :<br />
6
Paramètres :<br />
Dans le menu Projet, sélectionnez Propriétés. Dans la boîte qui<br />
apparaît, ajoutez gdiplus.lib dans le champ Dépendances<br />
supplémentaires de l’onglet Éditeur de liens / Entrée.<br />
7
Initialisation :<br />
Au début de votre programme, rajoutez les lignes suivantes :<br />
#include <br />
using namespace Gdiplus;<br />
ULONG_PTR m_gdiplusToken;<br />
8
Au début de votre programme, on initialise GDI+ avec les instructions<br />
suivantes :<br />
GdiplusStartupInput gdiplusStartupInput;<br />
GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);<br />
A la fin de votre programme, on quitte proprement GDI+ avec<br />
l’instruction suivante :<br />
GdiplusShutdown(m_gdiplusToken);<br />
9
3.2.2 La classe Graphics<br />
Toutes les fonctionnalités graphiques de GDI+ sont des méthodes de la<br />
classe Graphics.<br />
Un objet de classe Graphics s’obtient en fournissant au constructeur<br />
le handle de contexte de périphérique.<br />
Ex: dans WindowsProc() :<br />
case WM_PAINT:<br />
HDC hdc;<br />
hdc = BeginPaint(handle_fenetre, &PaintST);<br />
Graphics graphics(hdc);<br />
Pen crayon(Color(255, 255, 0, 0));<br />
graphics.DrawLine(&crayon, 0, 0, 200, 100);<br />
EndPaint(handle_fenetre, &PaintST);<br />
return 0;<br />
10
Obtenir un contexte de périphérique sur une fenêtre<br />
Deux possibilités :<br />
1. Dans WindowProc(), lors de l’interception du message WM_PAINT,<br />
on peut obtenir un DC avec BeginPaint() .<br />
case WM_PAINT :<br />
HDC hdc = BeginPaint(handle_fenetre,&PaintSt);<br />
2. Ailleurs, pour obtenir un DC il faut utiliser la fonction GetDC().<br />
HDC hdc = GetDC (handle_fenetre);<br />
11
Suppression de contexte de périphérique<br />
Lorsqu’on n’a plus besoin d’un DC, il faut le supprimer. La fonction à<br />
utiliser dépend de comment on a obtenu le DC :<br />
1. Si on a obtenu le DC avec BeginPaint() :<br />
HDC hdc = BeginPaint(handle_fenetre,&PaintSt);<br />
alors il faut le supprimer avec EndPaint() :<br />
EndPaint(handle_fenetre,&PaintSt);<br />
2. Si on a obtenu le DC avec GetDC() :<br />
HDC hdc = GetDC (handle_fenetre);<br />
alors il faut le supprimer avec ReleaseDC() :<br />
ReleaseDC(handle_fenetre, hdc);<br />
12
3.2.3 La classe Color<br />
En informatique, on représente n’importe quelle couleur par un mélange<br />
de 3 couleurs de base : le rouge, le vert, le bleu (système RVB).<br />
C’est le principe de la synthèse additive (vu en cours de 2ème année).<br />
Si on mélange du rouge, du vert et du bleu avec 256 nuances chacun,<br />
alors on peut obtenir 16,7 millions de couleurs (256x256x256).<br />
R V B<br />
Noir 0 0 0<br />
Bleu 0 0 255<br />
Vert 0 255 0<br />
Cyan 0 255 255<br />
Rouge 255 0 0<br />
Magenta 255 0 255<br />
Jaune 255 255 0<br />
Blanc 255 255 255<br />
13
GDI+ définit une couleur ARVB avec la classe Color.<br />
Nb bits<br />
=<br />
8 8 8 Nb bits 8 8 8 8<br />
=<br />
Un pixel RVB<br />
(24 bits)<br />
Un pixel ARVB<br />
(32 bits)<br />
Alpha = 0 : pixel complètement transparent<br />
Alpha = 255 : pixel complètement opaque<br />
0 < Alpha < 255 : pixel plus ou moins translucide<br />
A R V B<br />
Color c1(255, 255, 0, 0); // Rouge opaque<br />
Color c2(128, 0, 255, 0); // Vert à moitié transparent<br />
14
3.2.4 La classe Pen<br />
Classe de « crayon » définissant le style de tracé. On peut définir la<br />
couleur, l’épaisseur, les extrémités (flèche, rond, etc.), l’apparence<br />
(solide, pointillés, etc.).<br />
Constructeurs de la classe Pen :<br />
Pen::Pen(Color couleur); // Epaisseur = 1 pixel<br />
Pen::Pen(Color couleur, int epaisseur);<br />
Exemple :<br />
Pen crayon(Color(255, 255, 0, 0));<br />
// Crayon Rouge<br />
15
3.2.5 Tracé de lignes<br />
Pen crayon(Color(255, 255, 0, 0)); // Rouge<br />
graphics.DrawLine(&crayon, 10, 20, 200, 100);<br />
On définit d’abord un pointeur sur le crayon à utiliser, puis les<br />
coordonnées des deux extrémités.<br />
16
Définition des extrémités de lignes<br />
Pen crayon(Color(255, 0, 0, 255),20);<br />
crayon.SetLineCap(LineCapRound,<br />
LineCapArrowAnchor,<br />
DashCapRound);<br />
graphics.DrawLine(&crayon, 20, 20,200, 80);<br />
17
Effet de l’alpha blending<br />
Alpha faible (max=255) couleur<br />
transparente<br />
Pen crayon(Color(80, 0, 0, 255),40);<br />
graphics.DrawLine(&crayon, 10, 20,280, 150);<br />
18
3.2.6 Tracé de rectangles<br />
Graphics::DrawRectangle(Pen *crayon, int x, int y,<br />
int largeur, int hauteur);<br />
Exemple:<br />
graphics.DrawRectangle(&crayon, 100, 50, 80, 40);<br />
100<br />
50<br />
40<br />
80<br />
19
3.2.7 Tracé d’ellipses<br />
Graphics::DrawEllipse(Pen *crayon, int x, int y,<br />
int largeur, int hauteur);<br />
Exemple:<br />
graphics.DrawEllipse(&crayon, 100, 50, 80, 40);<br />
100<br />
50<br />
40<br />
80<br />
20
3.2.8 Tracé de polygones<br />
Point liste_points[] = {Point(60, 180), Point(30, 60)};<br />
Point(120, 80), Point(170, 20),<br />
Point(220, 100)};<br />
graphics.DrawPolygon(&crayon, liste_points, 5);<br />
(170, 20)<br />
(30, 60)<br />
(120, 80)<br />
(60, 180)<br />
(220, 100)<br />
class Point<br />
{<br />
int X,<br />
Y;<br />
}<br />
(définie par<br />
GDI+)<br />
21
3.2.9 Tracé de courbes splines<br />
Courbe passant par des points de contrôle.<br />
Point liste_points[] = {Point(60, 180), Point(30, 60)};<br />
Point(120, 80), Point(170, 20),<br />
Point(220, 100)};<br />
graphics.DrawCurve(&crayon, liste_points, 5, 1.0f);<br />
22
Dernier paramètre = « tension »<br />
graphics.DrawCurve(&crayon, liste_points, 5, 1.0f );<br />
Tension = 0.0f Tension = 1.0f Tension = 2.0f<br />
23
3.2.10 Tracé de courbes de Bézier<br />
Courbe influencée par des points de contrôle. La courbe passe par le<br />
premier point et par le dernier, mais pas par les autres.<br />
graphics.DrawBezier(&crayon, 60,180, 30,60,<br />
170,20, 220,100);<br />
(30, 60)<br />
(170, 20)<br />
(220, 100)<br />
(60, 180)<br />
24
3.2.11 Remplissage de formes avec des brosses<br />
On a vu comment afficher des contours de formes (rectangles,<br />
ellipses, polygones). Il existe l’équivalent de ces fonctions pour<br />
l’affichage de formes remplies.<br />
DrawRectan<br />
gle<br />
DrawEllip<br />
se<br />
DrawPolyg<br />
on<br />
FillRectan<br />
gle<br />
FillEllips<br />
e<br />
FillPolygo<br />
n<br />
Alors que les fonctions de tracé de contour de formes attendent en 1 er<br />
paramètre l’adresse d’un crayon, les fonctions de tracé de formes remplies<br />
attendent en 1 er paramètre l’adresse d’une brosse.<br />
25
Il existe différents types de brosses (« brush ») permettant de remplir<br />
des formes :<br />
La classe SolidBrush<br />
SolidBrush brosse(Color(255, 255, 0, 0));<br />
graphics.FillEllipse(&brosse, 100, 50, 160, 80);<br />
26
La classe HatchBrush<br />
HatchBrush brosse(HatchStyleVertical,<br />
Color(255, 0, 0, 255),<br />
Color(255, 0, 255, 0));<br />
graphics.FillEllipse(&brosse, 100, 50, 160, 80);<br />
GDI+ offre plus de 50 types de<br />
hachures.<br />
27
La classe TextureBrush<br />
Image image(L"rosace.bmp");<br />
TextureBrush brosse(&image);<br />
graphics.FillEllipse(&brosse, 100, 50, 160, 80);<br />
rosace.bmp<br />
Note: le constructeur<br />
de la classe Image<br />
(vue plus loin dans le<br />
cours) attend en<br />
paramètre un nom de<br />
fichier.<br />
La chaîne de<br />
caractères doit être<br />
codée en Unicode (2<br />
octets par caractère).<br />
28
3.2.12 Clipping<br />
Le « clipping » ou « découpage » permet de restreindre l’affichage à<br />
une région donnée.<br />
Region region(Rect(20, 30, 100, 50));<br />
graphics.DrawRectangle(&crayon, 20, 30, 100, 50);<br />
graphics.SetClip(®ion, CombineModeReplace);<br />
graphics.DrawLine(&crayon, 0, 0, 200, 200);<br />
Sans<br />
Avec<br />
Clipping d’une série<br />
d’ellipses par les<br />
contours d’un texte<br />
29
3.2.13 Antialiasing<br />
L’affichage se fait sur une matrice de pixels nombre limité de points,<br />
plus ou moins important en fonction de la résolution.<br />
Apparition de phénomènes « d’aliassage » (« aliasing » en anglais)<br />
comme des effets de « marches d’escalier »<br />
Affichage<br />
normal<br />
Affichage avec<br />
antialiassage<br />
Solution : utiliser des algorithmes « d’antialiassage » (« antialiasing ») qui<br />
vont calculer des pixels supplémentaires, affichés avec transparence, pour<br />
atténuer les effets de pixelisation.<br />
30
Une fonction GDI+ permet d’utiliser de l’antialiasing lors du tracé de<br />
lignes, courbes, rectangles, ellipses, etc. :<br />
Prototype :<br />
Graphics::SetSmoothingMode(SmoothingMode mode);<br />
Exemple :<br />
graphics.SetSmoothingMode(SmoothingModeAntiAlias);<br />
graphics.DrawEllipse(&crayon, 20, 20, 80, 40);<br />
graphics.SetSmoothingMode(SmoothingModeAntiAlias);<br />
graphics.DrawEllipse(&crayon, 20, 70, 80, 40);<br />
Remarque : L’antialiassage<br />
permet une meilleure qualité<br />
d’affichage mais est plus lent<br />
en raison des calculs<br />
supplémentaires.<br />
31
3.2.14 Affichage de texte<br />
FontFamily fontFamily(L"Times New Roman");<br />
Font font(&fontFamily, 24, FontStyleRegular, UnitPixel);<br />
PointF pointF(30.0f, 10.0f);<br />
SolidBrush solidBrush(Color(255, 0, 0, 255));<br />
graphics.DrawString(L"Hello",-1,&font,pointF,&solidBrush);<br />
32
Affichage de texte dans une zone rectangulaire<br />
FontFamily fontFamily(L"Arial");<br />
Font font(&fontFamily, 12, FontStyleBold, UnitPoint);<br />
RectF rectF(30.0f, 10.0f, 150.0f, 100.0f);<br />
SolidBrush solidBrush(Color(255, 0, 0, 255));<br />
graphics.DrawString(L"Affichage d'un texte dans un<br />
rectangle de 150x100 pixels", -1, &font, rectF, NULL,<br />
&solidBrush);<br />
33
Affichage de texte avec antialiasing<br />
Prototype :<br />
Graphics::SetTextRenderingHint(TextRenderingHint mode);<br />
Exemple :<br />
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);<br />
graphics.DrawString(L"Hello",-1,&font,PointF(30.0f, 60.0f),<br />
&solidBrush);<br />
mode =<br />
TextRenderingHintSingleBit<br />
PerPixel<br />
TextRenderingHintSystem<br />
Default<br />
TextRenderingHintAnt<br />
iAlias<br />
34
3.2.15 Affichage d’images<br />
Image : « bitmap » = matrice de pixels<br />
Pixel = « PICture ELement »<br />
Largeur (nb pixels)<br />
Un pixel<br />
Hauteur<br />
(nb<br />
pixels)<br />
Agrandissement d’une<br />
partie de l’image (œil)<br />
35
Pour afficher une image à l’écran avec le GDI :<br />
1. Charger l’image du disque vers la mémoire<br />
2. Copier l’image de la mémoire vers la fenêtre<br />
1 2<br />
Mémoire<br />
Disque<br />
Fenêtre<br />
36
Classe Image<br />
Pour afficher une image, il faut un objet de classe Graphics et un<br />
objet de classe Image. La classe Image permet de charger des images<br />
aux formats BMP, GIF, JPEG, PNG, TIFF, WMF, EMF, ICO.<br />
Image img(L"bird.jpg");<br />
Graphics graphics(hDC);<br />
img.GetWidth()<br />
img.GetHeight()<br />
37
Affichage<br />
La méthode DrawImage() de la classe Graphics a de nombreuses<br />
variantes (surcharges). En voici 3 :<br />
Image img(L"bird.jpg");<br />
Graphics graphics(hDC);<br />
1<br />
graphics.DrawImage(&img, 20, 10);<br />
38
2<br />
Graphics::DrawImage(Image* image,<br />
int xDestination, int yDestination,<br />
int xSource, int ySource,<br />
int largeurSource, int hauteurSource)<br />
xSource<br />
ySource<br />
xDestination<br />
yDestination<br />
hauteurSource<br />
largeurSource<br />
DrawImag<br />
e()<br />
Source<br />
Destination<br />
39
3<br />
Graphics::DrawImage(Image* image,<br />
Rect Dest,<br />
int xSource, int ySource,<br />
int largeurSource, int hauteurSource)<br />
xSource<br />
ySource<br />
hauteurSource<br />
Dest.top<br />
Dest.left<br />
largeurSource<br />
Dest.bottom<br />
Source<br />
DrawImag<br />
e()<br />
Dest.right<br />
Destination<br />
40
Gestion de la transparence<br />
Certains formats de fichiers d’image gèrent la transparence. Soit avec<br />
une seule couleur considérée comme transparente (ex: GIF), soit avec<br />
un canal alpha par pixel (ex: BMP, PNG, TGA).<br />
Quand on affiche une telle image, on peut voir ce qui avait déjà été<br />
affiché au travers des pixels transparents.<br />
Utile pour les « sprites » d’un jeu 2D, pour l’affichage de couches<br />
transparentes à la manière d’un dessin animé, etc.<br />
+<br />
Couleur<br />
41