Difference between revisions of "BGRABitmap tutorial 5/fr"
m (Fixed syntax highlighting; deleted category already in page template) |
|||
Line 20: | Line 20: | ||
Code correspondant dans ''OnPaint'' : | Code correspondant dans ''OnPaint'' : | ||
− | <syntaxhighlight>var temp,tex,mask: TBGRABitmap; | + | <syntaxhighlight lang="pascal">var temp,tex,mask: TBGRABitmap; |
begin | begin | ||
temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace))); | temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace))); | ||
Line 62: | Line 62: | ||
Code correspondant dans OnPaint : | Code correspondant dans OnPaint : | ||
− | <syntaxhighlight> | + | <syntaxhighlight lang="pascal"> |
var image,tex: TBGRABitmap; | var image,tex: TBGRABitmap; | ||
begin | begin | ||
Line 90: | Line 90: | ||
Avec l'inspecteur de projet, ajoutez un gestionnaire ''OnPaint'' : | Avec l'inspecteur de projet, ajoutez un gestionnaire ''OnPaint'' : | ||
− | <syntaxhighlight>procedure TForm1.FormPaint(Sender: TObject); | + | <syntaxhighlight lang="pascal">procedure TForm1.FormPaint(Sender: TObject); |
var image: TBGRABitmap; | var image: TBGRABitmap; | ||
size: single; | size: single; | ||
Line 137: | Line 137: | ||
Dans l'événement ''OnPaint'', ajoutez la sous-procédure : | Dans l'événement ''OnPaint'', ajoutez la sous-procédure : | ||
− | <syntaxhighlight> procedure DrawSun; | + | <syntaxhighlight lang="pascal"> procedure DrawSun; |
var layer,mask: TBGRABitmap; | var layer,mask: TBGRABitmap; | ||
begin | begin | ||
Line 166: | Line 166: | ||
Ajoutez la sous-procédure suivante dans l'événement ''OnPaint'' : | Ajoutez la sous-procédure suivante dans l'événement ''OnPaint'' : | ||
− | <syntaxhighlight> procedure ApplyLight; | + | <syntaxhighlight lang="pascal"> procedure ApplyLight; |
var layer: TBGRABitmap; | var layer: TBGRABitmap; | ||
begin | begin | ||
Line 182: | Line 182: | ||
=== Code résultant === | === Code résultant === | ||
− | <syntaxhighlight>uses BGRABitmap, BGRABitmapTypes; | + | <syntaxhighlight lang="pascal">uses BGRABitmap, BGRABitmapTypes; |
... | ... | ||
Line 262: | Line 262: | ||
Tout d'abord, le résultat sera stocké non pas dans un ''TBGRABitmap'', mais dans un ''TBGRALayeredBitmap'' : | Tout d'abord, le résultat sera stocké non pas dans un ''TBGRABitmap'', mais dans un ''TBGRALayeredBitmap'' : | ||
− | <syntaxhighlight> | + | |
+ | <syntaxhighlight lang="pascal"> | ||
var image: TBGRABitmap; | var image: TBGRABitmap; | ||
Line 278: | Line 279: | ||
Ensuite, les procédures qui ajoutent des éléments ne doivent pas dessiner directement sur l'image, mais ajouter des calques. Ainsi, le code suivant : | Ensuite, les procédures qui ajoutent des éléments ne doivent pas dessiner directement sur l'image, mais ajouter des calques. Ainsi, le code suivant : | ||
− | <syntaxhighlight> | + | |
+ | <syntaxhighlight lang="pascal"> | ||
image.PutImage(0,0,layer,dmDrawWithTransparency); | image.PutImage(0,0,layer,dmDrawWithTransparency); | ||
layer.Free; | layer.Free; | ||
− | </ | + | </syntaxhighlight> |
+ | |||
devient : | devient : | ||
− | <syntaxhighlight> | + | |
+ | <syntaxhighlight lang="pascal"> | ||
image.AddOwnedLayer(layer); | image.AddOwnedLayer(layer); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Et pour l'éclairage, le code suivant : | Et pour l'éclairage, le code suivant : | ||
− | <syntaxhighlight> | + | <syntaxhighlight lang="pascal"> |
image.BlendImage(0,0,layer,boMultiply); | image.BlendImage(0,0,layer,boMultiply); | ||
layer.Free; | layer.Free; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
devient : | devient : | ||
− | <syntaxhighlight> | + | <syntaxhighlight lang="pascal"> |
image.AddOwnedLayer(layer,boMultiply); | image.AddOwnedLayer(layer,boMultiply); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Le fond doit maintenant être aussi un calque. Ajoutez alors une nouvelle procédure : | Le fond doit maintenant être aussi un calque. Ajoutez alors une nouvelle procédure : | ||
− | <syntaxhighlight> | + | <syntaxhighlight lang="pascal"> |
procedure CreateBackground; | procedure CreateBackground; | ||
var layer: TBGRABitmap; | var layer: TBGRABitmap; | ||
Line 315: | Line 319: | ||
En déplaçant la création de l'image multicouche dans une fonction à part, ''CreateMyImage'', on obtient : | En déplaçant la création de l'image multicouche dans une fonction à part, ''CreateMyImage'', on obtient : | ||
− | <syntaxhighlight>function CreateMyImage(AWidth,AHeight: integer): TBGRALayeredBitmap; | + | <syntaxhighlight lang="pascal">function CreateMyImage(AWidth,AHeight: integer): TBGRALayeredBitmap; |
var image: TBGRALayeredBitmap; | var image: TBGRALayeredBitmap; | ||
size: single; | size: single; | ||
Line 395: | Line 399: | ||
A présent, créons un bouton avec le code suivant : | A présent, créons un bouton avec le code suivant : | ||
− | <syntaxhighlight> | + | <syntaxhighlight lang="pascal"> |
procedure TForm1.Button1Click(Sender: TObject); | procedure TForm1.Button1Click(Sender: TObject); | ||
var image: TBGRALayeredBitmap; | var image: TBGRALayeredBitmap; | ||
Line 409: | Line 413: | ||
[[BGRABitmap tutorial 4/fr|Tutoriel précédent (accès direct aux pixels)]] [[BGRABitmap tutorial 6/fr|Tutoriel suivant (styles de ligne)]] | [[BGRABitmap tutorial 4/fr|Tutoriel précédent (accès direct aux pixels)]] [[BGRABitmap tutorial 6/fr|Tutoriel suivant (styles de ligne)]] | ||
− | |||
− |
Revision as of 07:09, 10 February 2020
│ Deutsch (de) │ English (en) │ español (es) │ français (fr) │
Accueil | Tutoriel 1 | Tutoriel 2 | Tutoriel 3 | Tutoriel 4 | Tutoriel 5 | Tutoriel 6 | Tutoriel 7 | Tutoriel 8 | Tutoriel 9 | Tutoriel 10 | Tutoriel 11 | Tutoriel 12 | Edit
Ce tutoriel montre comment utiliser les couches et les masques sans utiliser d'image multicouche. Vous pouvez aussi utiliser TBGRALayeredBitmap qui se trouve dans l'unité BGRALayers pour superposer et combiner des couches. La deuxième partie du tutoriel montre comment adapter ce code pour utiliser une image multicouche.
Sans utiliser les images multicouches
Création d'un nouveau projet
Créez un nouveau projet et ajoutez la référence à BGRABitmap, de la même façon que dans le premier tutoriel.
Notions sur les masques
Un 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é.
Dans 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.
Code correspondant dans OnPaint :
var temp,tex,mask: TBGRABitmap;
begin
temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
//chargement d'une texture et redimensionnement
tex := TBGRABitmap.Create('texture.png');
BGRAReplace(tex,tex.Resample(128,80));
//on affiche l'image en haut à gauche
temp.PutImage(10,10,tex,dmDrawWithTransparency);
//création d'un masque avec une ellipse et un rectangle
mask := TBGRABitmap.Create(128,80,BGRABlack);
mask.FillEllipseAntialias(40,40,30,30,BGRAWhite);
mask.FillRectAntialias(60,40,100,70,BGRAWhite);
//on affiche le masque en haut à droite
temp.PutImage(150,10,mask,dmDrawWithTransparency);
//on applique le masque à l'image
tex.ApplyMask(mask);
//on affiche l'image résultante en bas à gauche
temp.PutImage(10,100,tex,dmDrawWithTransparency);
mask.Free;
tex.Free;
//on affiche le tout à l'écran
image.Draw(Canvas,0,0,True);
image.Free;
end;
Effacement de parties de l'image
Certaines 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.
Ici, 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.
Code correspondant dans OnPaint :
var image,tex: TBGRABitmap;
begin
image := TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
//chargement d'une texture et redimensionnement
tex := TBGRABitmap.Create('texture.png');
BGRAReplace(tex,tex.Resample(128,80));
//on affiche l'image en haut à gauche
image.PutImage(10,10,tex,dmDrawWithTransparency);
tex.EraseEllipseAntialias(40,40,30,30,255);
tex.EraseEllipseAntialias(80,40,30,30,128);
//on affiche l'image modifiée en bas à gauche
image.PutImage(10,100,tex,dmDrawWithTransparency);
tex.Free;
//on affiche le tout à l'écran
image.Draw(Canvas,0,0,True);
image.Free;
end;
Ajout d'un dessin
Avec l'inspecteur de projet, ajoutez un gestionnaire OnPaint :
procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
size: single;
procedure DrawMoon;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
image.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
end;
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight);
//calcul la place disponible dans les deux directions
if image.Height < image.Width then
size := image.Height
else
size := image.Width;
image.GradientFill(0,0,image.Width,image.Height,
BGRA(128,192,255),BGRA(0,0,255),
gtLinear,PointF(0,0),PointF(0,image.Height),
dmSet);
DrawMoon;
image.Draw(Canvas,0,0,True);
image.free;
end;
La procédure crée une image et la remplit avec un dégradé bleu. Il s'agit de la couche d'arrière-plan.
La 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.
Exécution du programme
Vous devriez voir un ciel bleu avec une lune. Quand vous redimensionnez la fenêtre, l'image est aussi redimensionnée.
Ajout d'un soleil
Dans l'événement OnPaint, ajoutez la sous-procédure :
procedure DrawSun;
var layer,mask: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,0),BGRA(255,0,0),
gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
dmSet);
mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
layer.ApplyMask(mask);
mask.Free;
image.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
end;
Cette 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.
Ajoutez un appel à cette procédure après la lune.
Exécution du programme
Vous devriez voir un ciel bleu avec une lune et un soleil. Quand la fenêtre est redimensionnée, l'image est aussi redimensionnée.
Ajout d'une lumière
Ajoutez la sous-procédure suivante dans l'événement OnPaint :
procedure ApplyLight;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,255),BGRA(64,64,64),
gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
dmSet);
image.BlendImage(0,0,layer,boMultiply);
layer.Free;
end;
Cette procédure dessine une couche avec un dégradé radial blanc. Elle est ensuite appliquée à l'image par multiplication.
Code résultant
uses BGRABitmap, BGRABitmapTypes;
...
procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
size: single;
procedure DrawMoon;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
image.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
end;
procedure DrawSun;
var layer,mask: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,0),BGRA(255,0,0),
gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
dmSet);
mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
layer.ApplyMask(mask);
mask.Free;
image.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
end;
procedure ApplyLight;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,255),BGRA(64,64,64),
gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
dmSet);
image.BlendImage(0,0,layer,boMultiply);
layer.Free;
end;
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight);
if image.Height < image.Width then
size := image.Height
else
size := image.Width;
image.GradientFill(0,0,image.Width,image.Height,
BGRA(128,192,255),BGRA(0,0,255),
gtLinear,PointF(0,0),PointF(0,image.Height),
dmSet);
DrawMoon;
DrawSun;
ApplyLight;
image.Draw(Canvas,0,0,True);
image.free;
end;
Exécution du programme
Vous devriez voir un ciel bleu avec une lune et un soleil, avec un effet de lumière.
En utilisant les images multicouches
L'unité BGRALayers fournit une classe TBGRALayeredBitmap qui permet de stocker une image multicouche. Vous allez l'utiliser pour sauvegarder votre dessin au format OpenRaster.
Quelques adaptations à faire
Tout d'abord, le résultat sera stocké non pas dans un TBGRABitmap, mais dans un TBGRALayeredBitmap :
var image: TBGRABitmap;
...
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight);
...
image.Draw(Canvas,0,0); //il n'y a pas de paramètre Opaque
image.free;
end;
Ensuite, les procédures qui ajoutent des éléments ne doivent pas dessiner directement sur l'image, mais ajouter des calques. Ainsi, le code suivant :
image.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
devient :
image.AddOwnedLayer(layer);
Et pour l'éclairage, le code suivant :
image.BlendImage(0,0,layer,boMultiply);
layer.Free;
devient :
image.AddOwnedLayer(layer,boMultiply);
Le fond doit maintenant être aussi un calque. Ajoutez alors une nouvelle procédure :
procedure CreateBackground;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,image.Width,image.Height,
BGRA(128,192,255),BGRA(0,0,255),
gtLinear,PointF(0,0),PointF(0,image.Height),
dmSet);
image.AddOwnedLayer(layer);
end;
Code résultant avec TBGRALayeredBitmap
En déplaçant la création de l'image multicouche dans une fonction à part, CreateMyImage, on obtient :
function CreateMyImage(AWidth,AHeight: integer): TBGRALayeredBitmap;
var image: TBGRALayeredBitmap;
size: single;
procedure CreateMoon;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
image.AddOwnedLayer(layer);;
end;
procedure CreateSun;
var layer,mask: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,0),BGRA(255,0,0),
gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
dmSet);
mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
layer.ApplyMask(mask);
mask.Free;
image.AddOwnedLayer(layer);
end;
procedure CreateLight;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,layer.Width,layer.Height,
BGRA(255,255,255),BGRA(64,64,64),
gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
dmSet);
image.AddOwnedLayer(layer,boMultiply);
end;
procedure CreateBackground;
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(image.Width,image.Height);
layer.GradientFill(0,0,image.Width,image.Height,
BGRA(128,192,255),BGRA(0,0,255),
gtLinear,PointF(0,0),PointF(0,image.Height),
dmSet);
image.AddOwnedLayer(layer);
end;
begin
image := TBGRALayeredBitmap.Create(AWidth,AHeight);
if image.Height < image.Width then
size := image.Height
else
size := image.Width;
CreateBackground;
CreateMoon;
CreateSun;
CreateLight;
result := image;
end;
{ TForm1 }
procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRALayeredBitmap;
begin
image := CreateMyImage(ClientWidth,ClientHeight);
image.Draw(Canvas,0,0);
image.free;
end;
Sauvegarder l'image dans un fichier OpenRaster
A présent, créons un bouton avec le code suivant :
procedure TForm1.Button1Click(Sender: TObject);
var image: TBGRALayeredBitmap;
begin
image := CreateMyImage(ClientWidth,ClientHeight);
image.SaveToFile('myimage.ora');
image.free;
end;
Ce 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.
Tutoriel précédent (accès direct aux pixels) Tutoriel suivant (styles de ligne)