Avec ce mini-tutoriel, je vous propose de dessiner quelques rectangles à l'aide de la bibliothèque BGRABitmap. Ce premier travail préparera les suivants qui mettront en œuvre des techniques plus complexes comme la transparence ou l'utilisation de textures.En guise d'illustration, une petite application abritera une TPaintBox pour le résultat des dessins et quelques TButton pour lancer leur exécution.
Voici tout d'abord l'interface visuelle qui ne comprend que des composants standard :
La fiche lfm correspondante est celle-ci :
| Code Pascal : | Sélectionner tout |
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | object MainForm: TMainForm Left = 250 Height = 525 Top = 184 Width = 905 Caption = 'Test de Rectangle - BGRABITMAP' ClientHeight = 525 ClientWidth = 905 OnCreate = FormCreate OnDestroy = FormDestroy Position = poScreenCenter LCLVersion = '1.6.2.0' object PaintBox: TPaintBox Left = 24 Height = 440 Top = 8 Width = 440 end object gbSimple: TGroupBox Left = 480 Height = 232 Top = 8 Width = 176 Caption = 'Simples' ClientHeight = 212 ClientWidth = 172 TabOrder = 0 object btnRectdmSet: TButton Left = 16 Height = 25 Top = 16 Width = 136 Caption = 'Rectangle (dmSet)' OnClick = btnRectdmSetClick TabOrder = 0 end object btnRectangleBGRAPixel: TButton Left = 16 Height = 25 Top = 48 Width = 136 Caption = 'Rectangle (BGRAPixel)' OnClick = btnRectangleBGRAPixelClick TabOrder = 1 end object btnRectangleBorderFillColor: TButton Left = 16 Height = 25 Top = 80 Width = 136 Caption = 'Rectangle (Border/Fill)' OnClick = btnRectangleBorderFillColorClick TabOrder = 2 end object btnFillRect: TButton Left = 16 Height = 25 Top = 112 Width = 136 Caption = 'FillRect (color)' OnClick = btnFillRectClick TabOrder = 3 end object btnRoundRect: TButton Left = 16 Height = 25 Top = 144 Width = 136 Caption = 'RoundRect (BGRAPixel)' OnClick = btnRoundRectClick TabOrder = 4 end object btnRoundRectBorderFillColor: TButton Left = 16 Height = 25 Top = 176 Width = 136 Caption = 'RoundRect (Border/Fill)' OnClick = btnRoundRectBorderFillColorClick TabOrder = 5 end end object btnClear: TButton Left = 24 Height = 25 Top = 480 Width = 75 Caption = 'Nettoyer' OnClick = btnClearClick TabOrder = 1 end end |
| Code Pascal : | Sélectionner tout |
1 2 3 4 | procedure TMainForm.FormCreate(Sender: TObject); begin bmpWork := TBGRABitmap.Create(PaintBox.Width, PaintBox.Height, BGRABlack); end; |
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 | private { private declarations } bmpWork: TBGRABitmap; public { public declarations } end; |
Bien sûr, la création oblige à créer son pendant pour libérer les ressources mobilisées. C'est dans le gestionnaire OnDestroy que cette libération trouvera tout naturellement sa place :
| Code Pascal : | Sélectionner tout |
1 2 3 4 | procedure TMainForm.FormDestroy(Sender: TObject); begin bmpWork.Free; end; |
La façon la plus simple de dessiner un rectangle est d'appeler la méthode Rectangle avec ses paramètres de base :
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 | procedure TMainForm.btnRectdmSetClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; begin bmpWork.Rectangle(20, 20, 100, 80, BGRAWhite, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
Après l'appel de la méthode désirée, il faut transférer le dessin virtuel sur le canevas de la zone réelle de dessin, ici celui de la TPaintBox : c'est le rôle de la méthode Draw qui prend pour paramètres le canevas de la zone dessin et les coordonnées du premier point supérieur gauche d'où il faut commencer à dessiner (ici, le point (0, 0) ).
Le résultat de la nouvelle méthode définie, lorsqu'on clique sur le bouton correspondant, est l'affichage d'un rectangle blanc sur la surface noire du TBGRABitmap.
L'emploi de constantes comme BGRABlack manque de souplesse. C'est pourquoi BGRABitmap offre des fonctions utiles comme BGRA qui construisent des données de type TBGRAPixel.
TBGRAPixel est un enregistrement étendu, c'est-à-dire incluant des propriétés et des méthodes, un peu à la manière des classes. En voici la déclaration :
| Code Pascal : | Sélectionner tout |
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 | TBGRAPixel = packed record private function GetClassIntensity: word; function GetClassLightness: word; procedure SetClassIntensity(AValue: word); procedure SetClassLightness(AValue: word); public {$IFDEF BGRABITMAP_RGBAPIXEL} red, green, blue, alpha: byte; {$ELSE} blue, green, red, alpha: byte; {$ENDIF} procedure FromRGB(ARed,AGreen,ABlue: Byte; AAlpha: Byte = 255); procedure FromColor(AColor: TColor; AAlpha: Byte = 255); procedure FromString(AStr: string); procedure FromFPColor(AColor: TFPColor); procedure ToRGB(out ARed,AGreen,ABlue,AAlpha: Byte); overload; procedure ToRGB(out ARed,AGreen,ABlue: Byte); overload; function ToColor: TColor; function ToString: string; function ToGrayscale(AGammaCorrection: boolean = true): TBGRAPixel; function ToFPColor: TFPColor; class Operator := (Source: TBGRAPixel): TColor; class Operator := (Source: TColor): TBGRAPixel; property Intensity: word read GetClassIntensity write SetClassIntensity; property Lightness: word read GetClassLightness write SetClassLightness; end; |
Pour revenir à la fonction BGRA, elle renvoie justement un enregistrement de type TBGRAPixel à partir de ces données de base :
| Code Pascal : | Sélectionner tout |
1 2 3 4 | {** Creates a pixel with given RGBA values } function BGRA(red, green, blue, alpha: byte): TBGRAPixel; overload; inline; {** Creates a opaque pixel with given RGB values } function BGRA(red, green, blue: byte): TBGRAPixel; overload; inline; |
En remplaçant la constante prédéfinie BGRABlack par le résultat de cette fonction, on gagne beaucoup en souplesse et en précision dans la couleur attendue :
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | procedure TMainForm.btnRectangleBGRAPixelClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; var Lc: TBGRAPixel; begin Lc := BGRA(255, 128, 128); bmpWork.Rectangle(60, 60, 140, 120, Lc, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 | procedure TMainForm.btnRectangleBGRAPixelClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; begin bmpWork.Rectangle(60, 60, 140, 120, BGRA(255, 128, 128), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
Il ne reste qu'à tester les autres méthodes disponibles à partir des éléments jusqu'alors étudiés.
On peut décider, par exemple, de remplir un rectangle. Il gardera sa bordure, mais son intérieur sera peint avec une couleur :
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 7 8 | procedure TMainForm.btnRectangleBorderFillColorClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; // mode: TDrawMode); override; begin bmpWork.Rectangle(100, 100, 180, 140, BGRA(255, 0, 0), BGRA(128, 128, 255), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 7 | procedure TMainForm.btnFillRectClick(Sender: TObject); // FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; // overload; begin bmpWork.FillRect(120, 120, 200, 160, BGRA(0, 255, 0), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | procedure TMainForm.btnRoundRectClick(Sender: TObject); // RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor: TBGRAPixel; // ADrawMode: TDrawMode = dmDrawWithTransparency); override; var Lc: TBGRAPixel; begin Lc := BGRA(255, 128, 128); bmpWork.RoundRect(260, 60, 340, 120, 12, 12, Lc, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
| Code Pascal : | Sélectionner tout |
1 2 3 4 5 6 7 8 | procedure TMainForm.btnRoundRectBorderFillColorClick(Sender: TObject); // RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor, FillColor: // TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override; begin bmpWork.RoundRect(300, 100, 380, 140, 15, 15, BGRA(255, 0, 0), BGRA(128, 128, 255), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; |
| Code Pascal : | Sélectionner tout |
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | { |========================================================================| | | | Projet : découverte de BGRABITMAP | | Description : Programme exemple 05 RECTANGLES | | Unité : main.pas | | Site : www.developpez.com | | Copyright : © Gilles VASSEUR 2017 | | | | Date: 17/02/2017 14:40:10 | | Version : 1.0.0 | | | |========================================================================| } unit main; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, BGRABitmapTypes, BGRABitmap; type { TMainForm } TMainForm = class(TForm) btnRectdmSet: TButton; btnRectangleBGRAPixel: TButton; btnRectangleBorderFillColor: TButton; btnFillRect: TButton; btnRoundRect: TButton; btnRoundRectBorderFillColor: TButton; btnClear: TButton; gbSimple: TGroupBox; PaintBox: TPaintBox; procedure btnClearClick(Sender: TObject); procedure btnFillRectClick(Sender: TObject); procedure btnRectangleBGRAPixelClick(Sender: TObject); procedure btnRectangleBorderFillColorClick(Sender: TObject); procedure btnRectdmSetClick(Sender: TObject); procedure btnRoundRectBorderFillColorClick(Sender: TObject); procedure btnRoundRectClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { private declarations } bmpWork: TBGRABitmap; public { public declarations } end; var MainForm: TMainForm; implementation {$R *.lfm} { TMainForm } procedure TMainForm.btnRectdmSetClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; begin bmpWork.Rectangle(20, 20, 100, 80, BGRAWhite, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnRoundRectBorderFillColorClick(Sender: TObject); // RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor, FillColor: // TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override; begin bmpWork.RoundRect(300, 100, 380, 140, 15, 15, BGRA(255, 0, 0), BGRA(128, 128, 255), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnRoundRectClick(Sender: TObject); // RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor: TBGRAPixel; // ADrawMode: TDrawMode = dmDrawWithTransparency); override; var Lc: TBGRAPixel; begin Lc := BGRA(255, 128, 128); bmpWork.RoundRect(260, 60, 340, 120, 12, 12, Lc, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnRectangleBGRAPixelClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; var Lc: TBGRAPixel; begin Lc := BGRA(255, 128, 128); bmpWork.Rectangle(60, 60, 140, 120, Lc, dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnFillRectClick(Sender: TObject); // FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; // overload; begin bmpWork.FillRect(120, 120, 200, 160, BGRA(0, 255, 0), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnClearClick(Sender: TObject); begin bmpWork.FillRect(0, 0, PaintBox.Width, PaintBox.Height, BGRABlack); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.btnRectangleBorderFillColorClick(Sender: TObject); // Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; // mode: TDrawMode); override; begin bmpWork.Rectangle(100, 100, 180, 140, BGRA(255, 0, 0), BGRA(128, 128, 255), dmSet); bmpWork.Draw(PaintBox.Canvas, 0, 0); end; procedure TMainForm.FormCreate(Sender: TObject); begin bmpWork := TBGRABitmap.Create(PaintBox.Width, PaintBox.Height, BGRABlack); end; procedure TMainForm.FormDestroy(Sender: TObject); begin bmpWork.Free; end; end. |
:Comme toujours, il est téléchargeable depuis [ATTACH]245745d1/a/a/a" />.
Vous avez lu gratuitement 19 698 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.