Sign in Join
Wiki copytemporary

BGRABitmap tutorial 3/fr: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: BGRABitmap tutorial 3/fr

OldNewLine
1+Ce tutoriel montre comment dessiner avec la souris.
2+
3+### Création d'un nouveau projet
4+
5+Créez un nouveau projet et ajoutez la référence à [[BGRABitmap]], de la même façon que dans [[BGRABitmap tutorial/fr|le premier tutoriel]].
6+
7+### Création d'une nouvelle image
8+
9+Ajoutez une variable privée à la fenêtre principale pour stocker l'image :
10+
11+``` pascal
12+ TForm1 = class(TForm)
13+ private
14+ { private declarations }
15+ image: TBGRABitmap;
16+ public
17+ { public declarations }
18+ end;
19+```
20+
21+Créez l'image quand la fenêtre est créée. Pour cela, double-cliquez sur la fenêtre. Une procédure devrait apparaître dans l'éditeur de code. Ajoutez l'instruction de création :
22+
23+``` pascal
24+procedure TForm1.FormCreate(Sender: TObject);
25+begin
26+ image := TBGRABitmap.Create(640,480,BGRAWhite); //crée une image 640x480
27+end;
28+```
29+
30+### Dessin de l'image
31+
32+Ajoutez un gestionnaire OnPaint. Pour cela, cliquez sur la fenêtre, allez dans l'inspecteur d'objet dans l'onglet événement, et double-cliquez sur la ligne *OnPaint*. Ensuite, ajoutez le code suivant :
33+
34+``` pascal
35+procedure TForm1.FormPaint(Sender: TObject);
36+begin
37+ PaintImage;
38+end;
39+```
40+
41+Ajoutez la procédure PaintImage :
42+
43+``` pascal
44+procedure TForm1.PaintImage;
45+begin
46+ image.Draw(Canvas,0,0,True);
47+end;
48+```
49+
50+Après avoir écrit cela, mettez le curseur texte sur *PaintImage* et pressez [[Ctrl-Shift-C]] pour ajouter la déclaration à l'interface.
51+
52+### Gestion de la souris
53+
54+Avec l'inspecteur d'objet, ajoutez des gestionnaires pour les événements *MouseDown* et *MouseMove* :
55+
56+``` pascal
57+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
58+ Shift: TShiftState; X, Y: Integer);
59+begin
60+ if Button = mbLeft then DrawBrush(X,Y);
61+end;
62+
63+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
64+ Y: Integer);
65+begin
66+ if ssLeft in Shift then DrawBrush(X,Y);
67+end;
68+```
69+
70+Ajoutez la procédure DrawBrush :
71+
72+``` pascal
73+procedure TForm1.DrawBrush(X, Y: Integer);
74+const radius = 5;
75+begin
76+ image.GradientFill(X-radius,Y-radius, X+radius,Y+radius,
77+ BGRABlack,BGRAPixelTransparent, gtRadial,
78+ PointF(X,Y), PointF(X+radius,Y), dmDrawWithTransparency);
79+
80+ PaintImage;
81+end;
82+```
83+
84+Après avoir écrit cela, mettez le curseur texte sur *DrawBrush* et pressez *Ctrl-Shift-C* pour ajouter la déclaration à l'interface.
85+
86+Cette procédure dessine un gradient radial (*gtRadial*) :
87+
88+- le rectangle encadrant est (X-radius,Y-radius, X+radius,Y+radius) ;
89+- le centre est noir et le bord transparent ;
90+- le centre est à (X,Y) et le bord à (X+radius,Y).
91+
92+### Code
93+
94+``` pascal
95+unit UMain;
96+
97+{$mode objfpc}{$H+}
98+
99+interface
100+
101+uses
102+ Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
103+ BGRABitmap, BGRABitmapTypes;
104+
105+type
106+ { TForm1 }
107+
108+ TForm1 = class(TForm)
109+ procedure FormCreate(Sender: TObject);
110+ procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
111+ Shift: TShiftState; X, Y: Integer);
112+ procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
113+ procedure FormPaint(Sender: TObject);
114+ private
115+ { private declarations }
116+ image: TBGRABitmap;
117+ procedure DrawBrush(X, Y: Integer);
118+ procedure PaintImage;
119+ public
120+ { public declarations }
121+ end;
122+
123+var
124+ Form1: TForm1;
125+
126+implementation
127+
128+{ TForm1 }
129+
130+procedure TForm1.FormCreate(Sender: TObject);
131+begin
132+ image := TBGRABitmap.Create(640,480,BGRAWhite);
133+end;
134+
135+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
136+ Shift: TShiftState; X, Y: Integer);
137+begin
138+ if Button = mbLeft then DrawBrush(X,Y);
139+end;
140+
141+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
142+ Y: Integer);
143+begin
144+ if ssLeft in Shift then DrawBrush(X,Y);
145+end;
146+
147+procedure TForm1.FormPaint(Sender: TObject);
148+begin
149+ PaintImage;
150+end;
151+
152+procedure TForm1.DrawBrush(X, Y: Integer);
153+const radius = 20;
154+begin
155+ image.GradientFill(X-radius,Y-radius, X+radius,Y+radius,
156+ BGRABlack,BGRAPixelTransparent,gtRadial,
157+ PointF(X,Y), PointF(X+radius,Y), dmDrawWithTransparency);
158+
159+ PaintImage;
160+end;
161+
162+procedure TForm1.PaintImage;
163+begin
164+ image.Draw(Canvas,0,0,True);
165+end;
166+
167+initialization
168+ {$I UMain.lrs}
169+
170+end.
171+```
172+
173+### Exécution du programme
174+
175+Vous pouvez dessiner sur la fenêtre.
176+
177+<figure>
178+<img src="BGRATutorial3.png" title="BGRATutorial3.png" />
179+<figcaption>BGRATutorial3.png</figcaption>
180+</figure>
181+
182+Remarquez que, selon la vitesse de déplacement de la souris, le tracé est plus ou moins foncé.
183+
184+### Obtenir un tracé continu
185+
186+Afin d'avoir un tracé continu, vous aurez besoin de variables supplémentaires :
187+
188+``` pascal
189+ TForm1 = class(TForm)
190+ ...
191+ private
192+ { private declarations }
193+ image: TBGRABitmap;
194+ mouseDrawing: boolean;
195+ mouseOrigin: TPoint;
196+```
197+
198+*mouseDrawing* sera à *True* pendant le tracé (avec le bouton gauche appuyé), et *mouseOrigin* sera le point de départ du segment à dessiner.
199+
200+Au moment du clic, le code devient un peu plus compliqué :
201+
202+``` pascal
203+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
204+ Shift: TShiftState; X, Y: Integer);
205+begin
206+ if Button = mbLeft then
207+ begin
208+ mouseDrawing := True;
209+ mouseOrigin := Point(X,Y);
210+ DrawBrush(X,Y,True);
211+ end;
212+end;
213+```
214+
215+On initialise le tracé en précisant la position de départ. Ensuite, on dessine un segment complet (notez le nouveau paramètre de *DrawBrush*). En effet, au début, le segment est complet, ce qui dans le cas d'un segment de longueur zéro correspond à un disque :
216+
217+<figure>
218+<img src="BGRATutorial3b.png" title="BGRATutorial3b.png" />
219+<figcaption>BGRATutorial3b.png</figcaption>
220+</figure>
221+
222+Au fur et à mesure, on ajoute la nouvelle partie tracée, qui est un segment ouvert. Par exemple :
223+
224+<figure>
225+<img src="BGRATutorial3c.png" title="BGRATutorial3c.png" />
226+<figcaption>BGRATutorial3c.png</figcaption>
227+</figure>
228+
229+Voilà pourquoi nous avons besoin d'un nouveau paramètre pour la fonction *DrawBrush*, qui devient :
230+
231+``` pascal
232+procedure TForm1.DrawBrush(X, Y: Integer; Closed: Boolean);
233+const brushRadius = 20;
234+begin
235+ image.DrawLineAntialias(X,Y,mouseOrigin.X,mouseOrigin.Y,BGRA(0,0,0,128),brushRadius,Closed);
236+ mouseOrigin := Point(X,Y);
237+
238+ PaintImage;
239+end;
240+```
241+
242+On transmet à *DrawLineAntialias* le paramètre *Closed*, indiquant si le segment est complet. Notez l'ordre des coordonnées. Le départ du segment et son point d'arrivée sont échangés. En effet, pour *DrawLineAntialias*, c'est la fin du segment qui est ouverte, alors que dans notre cas, c'est le début du segment qui est ouvert.
243+
244+Il faut mettre à jour la définition de *DrawBrush* dans l'interface.
245+
246+Le gestionnaire *MouseMove* devient :
247+
248+``` pascal
249+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
250+ Y: Integer);
251+begin
252+ if mouseDrawing then DrawBrush(X,Y,False);
253+end;
254+```
255+
256+Enfin, il faut ajouter un gestionnaire *MouseUp* pour mettre à jour *mouseDrawing* :
257+
258+``` pascal
259+procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
260+ Shift: TShiftState; X, Y: Integer);
261+begin
262+ if Button = mbLeft then
263+ mouseDrawing := False;
264+end;
265+```
266+
267+### Code
268+
269+``` pascal
270+unit UMain;
271+
272+{$mode objfpc}{$H+}
273+
274+interface
275+
276+uses
277+ Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
278+ BGRABitmap, BGRABitmapTypes;
279+
280+type
281+ { TForm1 }
282+
283+ TForm1 = class(TForm)
284+ procedure FormCreate(Sender: TObject);
285+ procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
286+ Shift: TShiftState; X, Y: Integer);
287+ procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
288+ procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
289+ Shift: TShiftState; X, Y: Integer);
290+ procedure FormPaint(Sender: TObject);
291+ private
292+ { private declarations }
293+ image: TBGRABitmap;
294+ mouseDrawing: boolean;
295+ mouseOrigin: TPoint;
296+ procedure DrawBrush(X, Y: Integer; Closed: boolean);
297+ procedure PaintImage;
298+ public
299+ { public declarations }
300+ end;
301+
302+var
303+ Form1: TForm1;
304+
305+implementation
306+
307+{ TForm1 }
308+
309+procedure TForm1.FormCreate(Sender: TObject);
310+begin
311+ image := TBGRABitmap.Create(640,480,BGRAWhite);
312+end;
313+
314+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
315+ Shift: TShiftState; X, Y: Integer);
316+begin
317+ if Button = mbLeft then
318+ begin
319+ mouseDrawing := True;
320+ mouseOrigin := Point(X,Y);
321+ DrawBrush(X,Y,True);
322+ end;
323+end;
324+
325+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
326+ Y: Integer);
327+begin
328+ if mouseDrawing then DrawBrush(X,Y,False);
329+end;
330+
331+procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
332+ Shift: TShiftState; X, Y: Integer);
333+begin
334+ if Button = mbLeft then
335+ mouseDrawing := False;
336+end;
337+
338+procedure TForm1.FormPaint(Sender: TObject);
339+begin
340+ PaintImage;
341+end;
342+
343+procedure TForm1.DrawBrush(X, Y: Integer; Closed: Boolean);
344+const brushRadius = 20;
345+begin
346+ image.DrawLineAntialias(X,Y,mouseOrigin.X,mouseOrigin.Y,BGRA(0,0,0,128),brushRadius,Closed);
347+ mouseOrigin := Point(X,Y);
348+
349+ PaintImage;
350+end;
351+
352+procedure TForm1.PaintImage;
353+begin
354+ image.Draw(Canvas,0,0,True);
355+end;
356+
357+initialization
358+ {$I UMain.lrs}
359+
360+end.
361+```
362+
363+### Exécution du programme
364+
365+À présent, le tracé est presque uniforme :
366+
367+<figure>
368+<img src="BGRATutorial3d.png" title="BGRATutorial3d.png" />
369+<figcaption>BGRATutorial3d.png</figcaption>
370+</figure>
371+
372+[[BGRABitmap tutorial 2/fr|Tutoriel précédent (chargement d'image)]] \| [[BGRABitmap tutorial 4/fr|Tutoriel suivant (accès direct aux pixels)]]
373+
374+---
375+*From the Free Pascal wiki, page "BGRABitmap tutorial 3/fr", as it stood on 2020-02-10 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history