Sign in Join
Wiki copytemporary

BGRABitmap tutorial 5/fr: what changed

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

OldNewLine
11Ce tutoriel montre comment utiliser les couches et les masques.
22
33La première partie montre comment faire sans utiliser d'image multicouche.
44
55La deuxième partie du tutoriel montre comment adapter le code pour utiliser une image multicouche *TBGRALayeredBitmap*, qui se trouve dans l'unité *BGRALayers*.
66
77## Sans utiliser les images multicouches
88
99### Création d'un nouveau projet
1010
1111Cré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]].
1212
1313### Notions sur les masques
1414
1515Un masque est une image en ton de gris. Quand on applique un masque sur une image, les parties de l'image qui se superposent avec les parties noires du masque sont effacées et deviennent transparentes, tandis que les parties qui se superposent avec les parties blanches du masque sont conservées. En d'autres termes, le masque est semblable à un canal alpha définissant une opacité. Si la valeur du masque est à zéro, cela se traduit par une transparence alors que si la valeur du masque est à 255, cela se traduit par une opacité.
1616
17-<figure>
18-<img src="BGRATutorial5d.png" title="BGRATutorial5d.png" />
19-<figcaption>BGRATutorial5d.png</figcaption>
20-</figure>
17+![](/wiki-images/0/05/BGRATutorial5d.png)
2118
2219Dans cet exemple, l'image de départ est en haut à gauche, le masque en haut à droite, et le résultat de l'application du masque sur l'image en bas à gauche.
2320
2421Code correspondant dans *OnPaint* :
2522
2623``` pascal
2724var temp,tex,mask: TBGRABitmap;
2825begin
2926 temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
3027
3128 //chargement d'une texture et redimensionnement
3229 tex := TBGRABitmap.Create('texture.png');
3330 BGRAReplace(tex,tex.Resample(128,80));
3431
3532 //on affiche l'image en haut à gauche
3633 temp.PutImage(10,10,tex,dmDrawWithTransparency);
3734
3835 //création d'un masque avec une ellipse et un rectangle
3936 mask := TBGRABitmap.Create(128,80,BGRABlack);
4037 mask.FillEllipseAntialias(40,40,30,30,BGRAWhite);
4138 mask.FillRectAntialias(60,40,100,70,BGRAWhite);
4239
4340 //on affiche le masque en haut à droite
4441 temp.PutImage(150,10,mask,dmDrawWithTransparency);
4542
4643 //on applique le masque à l'image
4744 tex.ApplyMask(mask);
4845
4946 //on affiche l'image résultante en bas à gauche
5047 temp.PutImage(10,100,tex,dmDrawWithTransparency);
5148
5249 mask.Free;
5350 tex.Free;
5451
5552 //on affiche le tout à l'écran
5653 image.Draw(Canvas,0,0,True);
5754 image.Free;
5855end;
5956```
6057
6158### Effacement de parties de l'image
6259
6360Certaines fonctions permettent d'effacer une ellipse, un rectangle, etc. Cela signifie que la partie concernée de l'image devient transparente. On peut donc dessiner un trou dans une image. Si le paramètre alpha est à 255, le trou est complètement transparent, sinon la partie devient semi-transparente.
6461
65-<figure>
66-<img src="BGRATutorial5e.png" title="BGRATutorial5e.png" />
67-<figcaption>BGRATutorial5e.png</figcaption>
68-</figure>
62+![](/wiki-images/6/62/BGRATutorial5e.png)
6963
7064Ici, une ellipse est effacée à gauche avec un paramètre alpha de 255, et une autre ellipse à droite est effacée avec un paramètre alpha à 128.
7165
7266Code correspondant dans OnPaint :
7367
7468``` pascal
7569var image,tex: TBGRABitmap;
7670begin
7771 image := TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
7872
7973 //chargement d'une texture et redimensionnement
8074 tex := TBGRABitmap.Create('texture.png');
8175 BGRAReplace(tex,tex.Resample(128,80));
8276
8377 //on affiche l'image en haut à gauche
8478 image.PutImage(10,10,tex,dmDrawWithTransparency);
8579
8680 tex.EraseEllipseAntialias(40,40,30,30,255);
8781 tex.EraseEllipseAntialias(80,40,30,30,128);
8882
8983 //on affiche l'image modifiée en bas à gauche
9084 image.PutImage(10,100,tex,dmDrawWithTransparency);
9185
9286 tex.Free;
9387
9488 //on affiche le tout à l'écran
9589 image.Draw(Canvas,0,0,True);
9690 image.Free;
9791end;
9892```
9993
10094### Ajout d'un dessin
10195
10296Avec l'inspecteur de projet, ajoutez un gestionnaire *OnPaint* :
10397
10498``` pascal
10599procedure TForm1.FormPaint(Sender: TObject);
106100var image: TBGRABitmap;
107101 size: single;
108102
109103 procedure DrawMoon;
110104 var layer: TBGRABitmap;
111105 begin
112106 layer := TBGRABitmap.Create(image.Width,image.Height);
113107 layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
114108 layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
115109 image.PutImage(0,0,layer,dmDrawWithTransparency);
116110 layer.Free;
117111 end;
118112
119113begin
120114 image := TBGRABitmap.Create(ClientWidth,ClientHeight);
121115
122116 //calcul la place disponible dans les deux directions
123117 if image.Height < image.Width then
124118 size := image.Height
125119 else
126120 size := image.Width;
127121
128122 image.GradientFill(0,0,image.Width,image.Height,
129123 BGRA(128,192,255),BGRA(0,0,255),
130124 gtLinear,PointF(0,0),PointF(0,image.Height),
131125 dmSet);
132126
133127 DrawMoon;
134128
135129 image.Draw(Canvas,0,0,True);
136130 image.free;
137131end;
138132```
139133
140134La procédure crée une image et la remplit avec un dégradé bleu. Il s'agit de la couche d'arrière-plan.
141135
142136La procédure *DrawMoon* crée une couche et dessine une lune dessus. En premier lieu, un disque blanc est dessiné, puis un plus petit disque est soustrait. Finalement, cette couche est fusionnée avec l'arrière-plan.
143137
144138### Exécution du programme
145139
146140Vous devriez voir un ciel bleu avec une lune. Quand vous redimensionnez la fenêtre, l'image est aussi redimensionnée.
147141
148-<figure>
149-<img src="Tutorial5a.png" title="Tutorial5a.png" />
150-<figcaption>Tutorial5a.png</figcaption>
151-</figure>
142+![](/wiki-images/1/15/Tutorial5a.png)
152143
153144### Ajout d'un soleil
154145
155146Dans l'événement *OnPaint*, ajoutez la sous-procédure :
156147
157148``` pascal
158149 procedure DrawSun;
159150 var layer,mask: TBGRABitmap;
160151 begin
161152 layer := TBGRABitmap.Create(image.Width,image.Height);
162153 layer.GradientFill(0,0,layer.Width,layer.Height,
163154 BGRA(255,255,0),BGRA(255,0,0),
164155 gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
165156 dmSet);
166157 mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
167158 mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
168159 layer.ApplyMask(mask);
169160 mask.Free;
170161 image.PutImage(0,0,layer,dmDrawWithTransparency);
171162 layer.Free;
172163 end;
173164```
174165
175166Cette procédure crée un dégradé radial de rouge et orange et applique un masque circulaire. Cela donne un disque coloré. Finalement, le disque est fusionné avec le fond.
176167
177168Ajoutez un appel à cette procédure après la lune.
178169
179170### Exécution du programme
180171
181172Vous devriez voir un ciel bleu avec une lune et un soleil. Quand la fenêtre est redimensionnée, l'image est aussi redimensionnée.
182173
183-<figure>
184-<img src="BGRATutorial5b.png" title="BGRATutorial5b.png" />
185-<figcaption>BGRATutorial5b.png</figcaption>
186-</figure>
174+![](/wiki-images/9/9b/BGRATutorial5b.png)
187175
188176### Ajout d'une lumière
189177
190178Ajoutez la sous-procédure suivante dans l'événement *OnPaint* :
191179
192180``` pascal
193181 procedure ApplyLight;
194182 var layer: TBGRABitmap;
195183 begin
196184 layer := TBGRABitmap.Create(image.Width,image.Height);
197185 layer.GradientFill(0,0,layer.Width,layer.Height,
198186 BGRA(255,255,255),BGRA(64,64,64),
199187 gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
200188 dmSet);
201189 image.BlendImage(0,0,layer,boMultiply);
202190 layer.Free;
203191 end;
204192```
205193
206194Cette procédure dessine une couche avec un dégradé radial blanc. Elle est ensuite appliquée à l'image par multiplication.
207195
208196### Code résultant
209197
210198``` pascal
211199uses BGRABitmap, BGRABitmapTypes;
212200
213201...
214202
215203procedure TForm1.FormPaint(Sender: TObject);
216204var image: TBGRABitmap;
217205 size: single;
218206
219207 procedure DrawMoon;
220208 var layer: TBGRABitmap;
221209 begin
222210 layer := TBGRABitmap.Create(image.Width,image.Height);
223211 layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
224212 layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
225213 image.PutImage(0,0,layer,dmDrawWithTransparency);
226214 layer.Free;
227215 end;
228216
229217 procedure DrawSun;
230218 var layer,mask: TBGRABitmap;
231219 begin
232220 layer := TBGRABitmap.Create(image.Width,image.Height);
233221 layer.GradientFill(0,0,layer.Width,layer.Height,
234222 BGRA(255,255,0),BGRA(255,0,0),
235223 gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
236224 dmSet);
237225 mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
238226 mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
239227 layer.ApplyMask(mask);
240228 mask.Free;
241229 image.PutImage(0,0,layer,dmDrawWithTransparency);
242230 layer.Free;
243231 end;
244232
245233 procedure ApplyLight;
246234 var layer: TBGRABitmap;
247235 begin
248236 layer := TBGRABitmap.Create(image.Width,image.Height);
249237 layer.GradientFill(0,0,layer.Width,layer.Height,
250238 BGRA(255,255,255),BGRA(64,64,64),
251239 gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
252240 dmSet);
253241 image.BlendImage(0,0,layer,boMultiply);
254242 layer.Free;
255243 end;
256244
257245begin
258246 image := TBGRABitmap.Create(ClientWidth,ClientHeight);
259247
260248 if image.Height < image.Width then
261249 size := image.Height
262250 else
263251 size := image.Width;
264252
265253 image.GradientFill(0,0,image.Width,image.Height,
266254 BGRA(128,192,255),BGRA(0,0,255),
267255 gtLinear,PointF(0,0),PointF(0,image.Height),
268256 dmSet);
269257
270258 DrawMoon;
271259 DrawSun;
272260 ApplyLight;
273261
274262 image.Draw(Canvas,0,0,True);
275263 image.free;
276264end;
277265```
278266
279267### Exécution du programme
280268
281269Vous devriez voir un ciel bleu avec une lune et un soleil, avec un effet de lumière.
282270
283-<figure>
284-<img src="Tutorial5c.png" title="Tutorial5c.png" />
285-<figcaption>Tutorial5c.png</figcaption>
286-</figure>
271+![](/wiki-images/f/f3/Tutorial5c.png)
287272
288273## En utilisant les images multicouches
289274
290275L'unité *BGRALayers* fournit une classe *TBGRALayeredBitmap* qui permet de stocker une image multicouche. Vous allez l'utiliser pour sauvegarder votre dessin au format *OpenRaster*.
291276
292277### Quelques adaptations à faire
293278
294279Tout d'abord, le résultat sera stocké non pas dans un *TBGRABitmap*, mais dans un *TBGRALayeredBitmap* :
295280
296281``` pascal
297282var image: TBGRALayeredBitmap;
298283
299284...
300285
301286begin
302287 image := TBGRALayeredBitmap.Create(ClientWidth,ClientHeight);
303288
304289...
305290
306291 image.Draw(Canvas,0,0); //il n'y a pas de paramètre Opaque
307292 image.free;
308293end;
309294```
310295
311296Ensuite, les procédures qui ajoutent des éléments ne doivent pas dessiner directement sur l'image, mais ajouter des calques. Ainsi, le code suivant :
312297
313298``` pascal
314299 image.PutImage(0,0,layer,dmDrawWithTransparency);
315300 layer.Free;
316301```
317302
318303devient :
319304
320305``` pascal
321306 image.AddOwnedLayer(layer);
322307```
323308
324309Et pour l'éclairage, le code suivant :
325310
326311``` pascal
327312 image.BlendImage(0,0,layer,boMultiply);
328313 layer.Free;
329314```
330315
331316devient :
332317
333318``` pascal
334319 image.AddOwnedLayer(layer,boMultiply);
335320```
336321
337322Le fond doit maintenant être aussi un calque. Ajoutez alors une nouvelle procédure :
338323
339324``` pascal
340325 procedure CreateBackground;
341326 var layer: TBGRABitmap;
342327 begin
343328 layer := TBGRABitmap.Create(image.Width,image.Height);
344329 layer.GradientFill(0,0,image.Width,image.Height,
345330 BGRA(128,192,255),BGRA(0,0,255),
346331 gtLinear,PointF(0,0),PointF(0,image.Height),
347332 dmSet);
348333 image.AddOwnedLayer(layer);
349334 end;
350335```
351336
352337### Code résultant avec *TBGRALayeredBitmap*
353338
354339En déplaçant la création de l'image multicouche dans une fonction à part, *CreateMyImage*, on obtient :
355340
356341``` pascal
357342function CreateMyImage(AWidth,AHeight: integer): TBGRALayeredBitmap;
358343var image: TBGRALayeredBitmap;
359344 size: single;
360345
361346 procedure CreateMoon;
362347 var layer: TBGRABitmap;
363348 begin
364349 layer := TBGRABitmap.Create(image.Width,image.Height);
365350 layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
366351 layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
367352 image.AddOwnedLayer(layer);;
368353 end;
369354
370355 procedure CreateSun;
371356 var layer,mask: TBGRABitmap;
372357 begin
373358 layer := TBGRABitmap.Create(image.Width,image.Height);
374359 layer.GradientFill(0,0,layer.Width,layer.Height,
375360 BGRA(255,255,0),BGRA(255,0,0),
376361 gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
377362 dmSet);
378363 mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
379364 mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
380365 layer.ApplyMask(mask);
381366 mask.Free;
382367 image.AddOwnedLayer(layer);
383368 end;
384369
385370 procedure CreateLight;
386371 var layer: TBGRABitmap;
387372 begin
388373 layer := TBGRABitmap.Create(image.Width,image.Height);
389374 layer.GradientFill(0,0,layer.Width,layer.Height,
390375 BGRA(255,255,255),BGRA(64,64,64),
391376 gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
392377 dmSet);
393378 image.AddOwnedLayer(layer,boMultiply);
394379 end;
395380
396381 procedure CreateBackground;
397382 var layer: TBGRABitmap;
398383 begin
399384 layer := TBGRABitmap.Create(image.Width,image.Height);
400385 layer.GradientFill(0,0,image.Width,image.Height,
401386 BGRA(128,192,255),BGRA(0,0,255),
402387 gtLinear,PointF(0,0),PointF(0,image.Height),
403388 dmSet);
404389 image.AddOwnedLayer(layer);
405390 end;
406391
407392begin
408393 image := TBGRALayeredBitmap.Create(AWidth,AHeight);
409394
410395 if image.Height < image.Width then
411396 size := image.Height
412397 else
413398 size := image.Width;
414399
415400 CreateBackground;
416401 CreateMoon;
417402 CreateSun;
418403 CreateLight;
419404
420405 result := image;
421406end;
422407
423408{ TForm1 }
424409
425410procedure TForm1.FormPaint(Sender: TObject);
426411var image: TBGRALayeredBitmap;
427412begin
428413 image := CreateMyImage(ClientWidth,ClientHeight);
429414 image.Draw(Canvas,0,0);
430415 image.free;
431416end;
432417```
433418
434419### Sauvegarder l'image dans un fichier OpenRaster
435420
436421A présent, créons un bouton avec le code suivant :
437422
438423``` pascal
439424procedure TForm1.Button1Click(Sender: TObject);
440425var image: TBGRALayeredBitmap;
441426begin
442427 image := CreateMyImage(ClientWidth,ClientHeight);
443428 image.SaveToFile('myimage.ora');
444429 image.free;
445430end;
446431```
447432
448433Ce code est relativement évident : il crée une image de la taille de la fenêtre et la sauvegarde au format *OpenRaster* (.ora). Vous pouvez ensuite importer cette image dans Krita, Gimp ou Paint.NET.
449434
450435[[BGRABitmap tutorial 4/fr|Tutoriel précédent (accès direct aux pixels)]] [[BGRABitmap tutorial 6/fr|Tutoriel suivant (styles de ligne)]]
451436
452437---
453438*From the Free Pascal wiki, page "BGRABitmap tutorial 5/fr", as it stood on 2024-02-15 after a change by Circular, 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