BGRABitmap tutorial 4/fr: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | Ce tutoriel montre comment accéder directement aux pixels et utiliser les modèles de couleurs. | |
| 2 | 2 | ||
| 3 | 3 | ### Création d'un nouveau projet | |
| 4 | 4 | ||
| 5 | 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 | 6 | ||
| 7 | 7 | ### Dessin avec accès direct aux pixels | |
| 8 | 8 | ||
| 9 | 9 | Avec l'inspecteur d'objet, ajoutez un gestionnaire *OnPaint* et écrivez : | |
| 10 | 10 | ||
| 11 | 11 | ``` pascal | |
| 12 | 12 | procedure TForm1.FormPaint(Sender: TObject); | |
| 13 | 13 | var x,y: integer; | |
| 14 | 14 | p: PBGRAPixel; | |
| 15 | 15 | image: TBGRABitmap; | |
| 16 | 16 | begin | |
| 17 | 17 | image := TBGRABitmap.Create(ClientWidth,ClientHeight); | |
| 18 | 18 | ||
| 19 | 19 | for y := 0 to image.Height-1 do | |
| 20 | 20 | begin | |
| 21 | 21 | p := image.Scanline[y]; | |
| 22 | 22 | for x := 0 to image.Width-1 do | |
| 23 | 23 | begin | |
| 24 | 24 | p^.red := x*256 div image.Width; | |
| 25 | 25 | p^.green := y*256 div image.Height; | |
| 26 | 26 | p^.blue := 0; | |
| 27 | 27 | p^.alpha := 255; | |
| 28 | 28 | inc(p); | |
| 29 | 29 | end; | |
| 30 | 30 | end; | |
| 31 | 31 | image.InvalidateBitmap; // changé par accès direct | |
| 32 | 32 | ||
| 33 | 33 | image.Draw(Canvas,0,0,True); | |
| 34 | 34 | image.free; | |
| 35 | 35 | end; | |
| 36 | 36 | ``` | |
| 37 | 37 | ||
| 38 | 38 | Cette procédure crée une image de la même taille que la zone client disponible. Ensuite, les boucles parcourent tous les pixels pour calculer un dégradé bidimensionnel. Finalement, l'image est affichée et libérée. | |
| 39 | 39 | ||
| 40 | 40 | Pour accéder aux données de l'image, vous pouvez soit utiliser *Data*, si vous ne vous souciez pas de l'ordre des lignes, ou *Scanline* pour accéder à une ligne spécifique. À l'intérieur d'une ligne, les pixels sont rangés de gauche à droite. | |
| 41 | 41 | ||
| 42 | 42 | Ici, chaque composante est définie : | |
| 43 | 43 | ||
| 44 | 44 | ``` pascal | |
| 45 | 45 | p^.red := x*256 div image.Width; | |
| 46 | 46 | ``` | |
| 47 | 47 | ||
| 48 | 48 | définit une composante de rouge variant de 0 à 255, de gauche à droite. La valeur maximale *image.Width* n'est jamais atteinte par x si bien que la composante rouge n'atteint jamais 256. | |
| 49 | 49 | ||
| 50 | 50 | ### Exécution du programme | |
| 51 | 51 | ||
| 52 | 52 | Vous devriez voir une fenêtre avec un dégradé où les coins sont noir, rouge, jaune et vert. Quand vous redimensionnez la fenêtre, le dégradé est aussi redimensionné. | |
| 53 | 53 | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - | ||
| 54 | + |  | |
| 58 | 55 | ||
| 59 | 56 | ### Espace de couleur HSLA | |
| 60 | 57 | ||
| 61 | 58 | Vous pouvez utiliser la teinte (*hue*), la saturation et la luminosité (*lightness*). Pour cela, déclarez un pixel *THSLAPixel*. Les valeurs vont de 0 à 65535. Pour le convertir en RGB standard, utilisez *HSLAToBGRA*. | |
| 62 | 59 | ||
| 63 | 60 | ``` pascal | |
| 64 | 61 | procedure TForm1.FormPaint(Sender: TObject); | |
| 65 | 62 | var x,y: integer; | |
| 66 | 63 | p: PBGRAPixel; | |
| 67 | 64 | image: TBGRABitmap; | |
| 68 | 65 | hsla: THSLAPixel; | |
| 69 | 66 | begin | |
| 70 | 67 | image := TBGRABitmap.Create(ClientWidth,ClientHeight); | |
| 71 | 68 | hsla.lightness := 32768; | |
| 72 | 69 | hsla.alpha := 65535; | |
| 73 | 70 | for y := 0 to image.Height-1 do | |
| 74 | 71 | begin | |
| 75 | 72 | p := image.Scanline[y]; | |
| 76 | 73 | hsla.saturation := y*65536 div image.Height; | |
| 77 | 74 | for x := 0 to image.Width-1 do | |
| 78 | 75 | begin | |
| 79 | 76 | hsla.hue := x*65536 div image.Width; | |
| 80 | 77 | p^:= HSLAToBGRA(hsla); | |
| 81 | 78 | inc(p); | |
| 82 | 79 | end; | |
| 83 | 80 | end; | |
| 84 | 81 | image.InvalidateBitmap; // changé par accès direct | |
| 85 | 82 | ||
| 86 | 83 | image.Draw(Canvas,0,0,True); | |
| 87 | 84 | image.free; | |
| 88 | 85 | end; | |
| 89 | 86 | ``` | |
| 90 | 87 | ||
| 91 | - | ||
| 92 | - | ||
| 93 | - | ||
| 94 | - | ||
| 88 | + |  | |
| 95 | 89 | ||
| 96 | 90 | #### Correction des couleurs | |
| 97 | 91 | ||
| 98 | 92 | Les couleurs HSLA sont gérées avec la correction gamma, mais il y a d'autres corrections possibles. Par exemple, le H signifie "hue", c'est-à-dire teinte. Dans la version classique du modèle HSLA, chaque gamme entre les couleurs primaires rouge/vert/bleu est représentée par 120°, soit 21845 couleurs dans un *THSLAPixel*. Cependant, nous ne percevons pas les mêmes différences de couleurs dans les différentes gammes. Les fonctions *HtoG* et *GtoH* permettent d'appliquer ou non une correction. G signifie que les gammes ne sont pas égales. Donc, vous pouvez obtenir des gammes de taille différentes en écrivant : | |
| 99 | 93 | ||
| 100 | 94 | ``` pascal | |
| 101 | 95 | hsla.hue := GtoH(x*65536 div image.Width); | |
| 102 | 96 | ``` | |
| 103 | 97 | ||
| 104 | 98 | La gamme des oranges par exemple est alors plus étendue. Enfin, dans le modèle HSLA, l'intensité lumineuse L ne correspond pas à la luminosité perçue. Vous pouvez alors utiliser les fonctions *GSBAToBGRA* et *BGRAToGSBA* à la place des fonctions *HSLAToBGRA* et *BGRAToHSLA*. Le G signifie que la teinte n'est pas uniforme et le B que c'est la luminosité réelle (*brightness*) qui est prise en compte. Dans ce cas, il n'est pas nécessaire de faire la conversion avec *GtoH* et *HtoG*. | |
| 105 | 99 | ||
| 106 | 100 | Le code précédent devient donc simplement : | |
| 107 | 101 | ||
| 108 | 102 | ``` pascal | |
| 109 | 103 | procedure TForm1.FormPaint(Sender: TObject); | |
| 110 | 104 | var x,y: integer; | |
| 111 | 105 | p: PBGRAPixel; | |
| 112 | 106 | image: TBGRABitmap; | |
| 113 | 107 | hsla: THSLAPixel; | |
| 114 | 108 | begin | |
| 115 | 109 | image := TBGRABitmap.Create(ClientWidth,ClientHeight); | |
| 116 | 110 | hsla.lightness := 32768; | |
| 117 | 111 | hsla.alpha := 65535; | |
| 118 | 112 | for y := 0 to image.Height-1 do | |
| 119 | 113 | begin | |
| 120 | 114 | p := image.Scanline[y]; | |
| 121 | 115 | hsla.saturation := y*65536 div image.Height; | |
| 122 | 116 | for x := 0 to image.Width-1 do | |
| 123 | 117 | begin | |
| 124 | 118 | hsla.hue := x*65536 div image.Width; | |
| 125 | 119 | p^:= GSBAToBGRA(hsla); | |
| 126 | 120 | inc(p); | |
| 127 | 121 | end; | |
| 128 | 122 | end; | |
| 129 | 123 | image.InvalidateBitmap; // changé par accès direct | |
| 130 | 124 | ||
| 131 | 125 | image.Draw(Canvas,0,0,True); | |
| 132 | 126 | image.free; | |
| 133 | 127 | end; | |
| 134 | 128 | ``` | |
| 135 | 129 | ||
| 136 | 130 | Notez que le type *THSLAPixel* est utilisé, indifféremment du modèle de couleur. | |
| 137 | 131 | ||
| 138 | 132 | ### Exécution du programme | |
| 139 | 133 | ||
| 140 | 134 | Avec la correction des couleurs, le dégradé est beaucoup plus progressif et ressemble à ce qu'on obtient avec le modèle de couleur Lab. | |
| 141 | 135 | ||
| 142 | - | ||
| 143 | - | ||
| 144 | - | ||
| 145 | - | ||
| 136 | + |  | |
| 146 | 137 | ||
| 147 | 138 | [[BGRABitmap tutorial 3/fr|Tutoriel précédent (dessiner avec la souris)]] [[BGRABitmap tutorial 5/fr|Tutoriel suivant (couches et masques)]] | |
| 148 | 139 | ||
| 149 | 140 | --- | |
| 150 | 141 | *From the Free Pascal wiki, page "BGRABitmap tutorial 4/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).* |
