IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Gilles Vasseur - Pascal et compagnie

Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité

Noter ce billet
par , 23/03/2018 à 08h29 (839 Affichages)
Un élément que nous aimerions déterminer est sans doute l'opacité des images, car cette fonctionnalité nous permettrait de les dessiner avec une transparence plus ou moins forte. La bibliothèque BGRABitmap propose de nombreuses routines dont un des paramètres est justement l'opacité.

Introduction de l'opacité

Le degré de transparence est fourni dans la composition d'une couleur par un entier de 0 à 255 appelé canal alpha. La valeur 255 rend un pixel totalement opaque tandis que la valeur 0 le rend totalement transparent. Les valeurs intermédiaires permettent de nuancer cette transparence.
Toujours dans un souci d'une meilleure lisibilité de notre code, nous allons donc définir une constante fixant la valeur maximale de l'opacité :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls, ComCtrls, BGRABitmapTypes, BGRABitmap;

const
  C_DefaultSpeed = 80;
  C_MaxOpacity = 255; // opacité maximale
Plutôt que de calculer à la main l'opacité pour un pourcentage donné de transition réalisée, nous allons créer une fonction qui la calculera automatiquement selon une fonction linéaire tout en offrant à l'utilisateur la possibilité d'activer ou de désactiver ce traitement particulier.

Il nous faut par conséquent un champ de type booléen pour l'activation de l'opacité, une propriété manipulant ce champ et une fonction renvoyant la valeur de l'opacité suivant l'état du système à un temps déterminé. Ces éléments sont déclarés dans la classe abritant la fiche principale :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
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
{ TMainForm }
 
  TMainForm = class(TForm)
    btnGo: TButton;
    cbOpacity: TCheckBox;
    imgFrom: TImage;
    imgTo: TImage;
    imgResult: TImage;
    lblSpeed: TLabel;
    tbarSpeed: TTrackBar;
    procedure btnGoClick(Sender: TObject);
    procedure cbOpacityChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure tbarSpeedChange(Sender: TObject);
  private
    fBGRAFrom, fBGRATo: TBGRABitmap;
    fStep: Byte;
    fSpeed: Byte;
    fWithOpacity: Boolean; // opacité
    procedure SetWithOpacity(AValue: Boolean);
    procedure SetSpeed(AValue: Byte);
  public
    function Opacity(Up: Boolean = True): Byte; // opacité à utiliser
    property Speed: Byte read fSpeed write SetSpeed default C_DefaultSpeed;
    property WithOpacity: Boolean read fWithOpacity write SetWithOpacity;
  end;

Le traitement de la propriété WithOpacity est similaire à celui correspondant à la propriété Speed :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
procedure TMainForm.SetWithOpacity(AValue: Boolean);
// *** détermination de l'opacité ***
begin
  if fWithOpacity = AValue then
    Exit;
  fWithOpacity := AValue;
end;

La propriété WithOpacity appelle la même remarque que sa consœur : en l'état, une simple écriture de la valeur du champ interne aurait été possible, mais l'écriture d'une méthode particulière prépare des extensions comme un gestionnaire d'événement dédié.

D'ores et déjà, nous pouvons réagir au changement de la case à cocher chargée de gérer la prise en compte ou non de l'opacité. En double-cliquant sur cette case à cocher, Lazarus crée un gestionnaire que nous renseignerons ainsi :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
procedure TMainForm.cbOpacityChange(Sender: TObject);
// *** gestion de la transparence ***
begin
  WithOpacity := cbOpacity.Checked;
end;

L'opacité sera dorénavant active si la case est cochée. Par défaut, nous savons que le champ sera initialisé à False lors de la création de la fiche : il n'est donc pas nécessaire de lui donner cette valeur dans la méthode OnCreate.

Reste bien sûr la fonction Opacity introduite par nos soins. Son paramètre fixé par défaut à True indiquera si l'opacité doit augmenter avec le pourcentage réalisé de transition ou si elle doit au contraire diminuer. Cette possibilité nous permettra par exemple de faire apparaître une image tout en faisant disparaître l'autre.

Il nous faut donc distinguer plusieurs cas, suivant si la prise en compte de l'opacité est activée ou non, et suivant la valeur du paramètre Up. Voici le code proposé :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
function TMainForm.Opacity(Up: Boolean): Byte;
// *** calcul de l'opacité en fonction du pourcentage effectué ***
begin
  if fWithOpacity then
  begin
    if Up then
      Result := fStep * C_MaxOpacity div 100
    else
      Result := C_MaxOpacity - fStep * C_MaxOpacity div 100;
end
  else
    Result := C_MaxOpacity;
end;

La méthode ne pose pas de problèmes insurmontables. Il s'agit de ramener un pourcentage à une valeur comprise entre 0 et 255, c'est-à-dire dans l'intervalle autorisé des valeurs de l'opacité. Si l'opacité est inactive, l'image sera totalement opaque. Si le paramètre de la fonction est à False, une soustraction permet de faire décroître l'opacité.

Pour que tout cela fonctionne, il faut encore modifier les paramètres des méthodes de BGRABitmap qui gèrent la transparence. Le gestionnaire du clic sur le bouton devient alors :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
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
procedure TMainForm.btnGoClick(Sender: TObject);
// *** dessin ***
var
  LBGRATemp: TBGRABitmap;
  LY, LX: Integer;
begin
  btnGo.Enabled := False;
  LBGRATemp := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
  try
    LX := 0;
    LY := 0;
    fStep := 0;
    repeat
      Inc(fStep);
      LBGRATemp.FillRect(ClientRect, BGRABlack);
      LBGRATemp.PutImage(0, 0, fBGRAFrom, dmSet, Opacity(False)); // opacité !
      // traitement ici...
      LY := - imgResult.ClientHeight + imgResult.ClientHeight * fStep div
      100; // OVERDOWN
      LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity); // opacité !
      LBGRATemp.Draw(imgResult.Canvas, 0, 0);
      imgResult.Repaint;
      sleep(100 - fSpeed);
    until fStep = 100;
  finally
    LBGRATemp.Free;
    btnGo.Enabled := True;
  end;
end;

Nous avons choisi de faire disparaître peu à peu l'image d'origine tandis que l'image qui la recouvre voit sa visibilité s'accroître dans les mêmes proportions. Il suffit de lancer notre application qui servira de modèle avec l'unique transition que nous connaissons et de cocher la case marqué « Transparence » pour obtenir des images comme celle-ci :


Nom : 00b1.png
Affichages : 114
Taille : 289,1 Ko

On voit que le rouge-gorge commence à se dessiner alors que la mésange et le chardonneret s'évanouissent déjà.

La première partie de notre travail s'achève ici : nous avons installé la bibliothèque BGRABitmap et réalisé l'application qui nous servira de modèle pour les tests. Grâce à elle, nous aurons deux images pour travailler et de quoi gérer l'opacité et la vitesse d'affichage de la résultante du traitement par nos transitions. Le billet suivant concernera bien évidemment les transitions elles-mêmes.

Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Viadeo Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Twitter Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Google Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Facebook Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Digg Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Delicious Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog MySpace Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (VI) - Introduction de l'opacité » dans le blog Yahoo

Mis à jour 26/03/2018 à 20h57 par gvasseur58

Catégories
Programmation , Free Pascal , Lazarus , Graphisme

Commentaires