Voir le flux RSS

Blog de Gilles Vasseur - Pascal et compagnie

Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite)

Noter ce billet
par , 14/05/2018 à 09h00 (250 Affichages)
Après les bandes verticales et horizontales, il serait apprécié d'obtenir des bandes entrelacées. c'est justement l'objet du billet du jour .

Entrelacer des bandes

Entrelacer des bandes repose sur le même principe que leur dessin progressif horizontalement ou verticalement, à savoir l'agrandissement progressif de rectangles selon une seule dimension. La différence essentielle tient au fait qu'un rectangle suivant un autre croîtra à partir du bord opposé de l'image. Un schéma représentant le masque de ce mécanisme si l'entrelacement est horizontal pourra être celui-ci :

Nom : interlacedH.png
Affichages : 32
Taille : 1,9 Ko

Tout de suite apparaît un problème spécifique à ce type de transition : commencerons-nous par la bande qui se déplace vers la droite ou au contraire par celle qui se dirige vers la gauche ? Pour le dessin, nous utiliserons une itération, aussi pourrons-nous décider du dessin à partir de la parité du numéro de la bande. Nous baptiserons StripsInterlacedLeftRight la première transition et StripsInterlacedRightLeft la seconde.

Le code proposé pour StripsInterlacedLeftRight tient compte de la difficulté évoquée en utilisant la fonction Odd :

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
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
procedure TMainForm.btnGoClick(Sender: TObject);
// *** dessin ***
var
  LBGRAFrom, LBGRATo, LBGRAMask: TBGRABitmap;
  LY, LX, LI, LStripHeight: Integer;
 
  function NumberOfStrips: Integer;
  const
    C_DefaultNumberOfStrips = 20;
  begin
    if imgResult.ClientHeight < 10 then
      Result := 1
    else
    if (imgResult.ClientHeight < 300) then
      Result := 5
    else
    if (imgResult.ClientHeight < 1000) then
      Result := imgResult.ClientHeight div C_DefaultNumberOfStrips
    else
      Result := 30;
  end;
begin
  btnGo.Enabled := False;
  LStripHeight := 1 + imgResult.ClientHeight div NumberOfStrips;
  LBGRAFrom := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
  try
    LBGRATo := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
    try
      LBGRAMask := TBGRABitmap.Create(imgResult.ClientWidth, ClientHeight, BGRABlack);
      try
        fStep := 0;
        repeat
          Inc(fStep);
          LX := 0;
          LY := 0;
          LBGRAFrom.FillRect(ClientRect, BGRABlack);
          LBGRAFrom.PutImage(LX, LY, fBGRAFrom, dmDrawWithTransparency, Opacity(False));
          for LI := 0 to NumberOfStrips do
            if Odd(LI) then
              LBGRAMask.FillRectAntialias(imgResult.ClientWidth
                - imgResult.ClientWidth * fStep div 100, LStripHeight * LI,
               imgResult.ClientWidth,
               LStripHeight * (LI + 1), BGRAWhite, False)
            else
              LBGRAMask.FillRectAntialias(0, LStripHeight * LI,
               imgResult.ClientWidth * fStep div 100,
               LStripHeight * (LI + 1), BGRAWhite, False);
          LBGRATo.PutImage(0, 0, fBGRATo, dmSet);
          LBGRATo.ApplyMask(LBGRAMask);
          LBGRAFrom.PutImage(0, 0, LBGRATo, dmDrawWithTransparency, Opacity);
          LBGRAFrom.Draw(imgResult.Canvas, 0, 0);
          imgResult.Repaint;
          sleep(100 - fSpeed);
        until fStep = 100;
      finally
        LBGRAMask.Free;
      end;
    finally
      LBGRATo.Free;
    end;
  finally
    LBGRAFrom.Free;
    btnGo.Enabled := True;
  end;
end;

Pour passer de StripsInterlacedLeftRight à StripsInterlacedRightLeft, il nous faudra tout simplement inverser le résultat de la fonction Odd :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
for LI := 0 to NumberOfStrips - 1 do
            if not Odd(LI) then // ici, l'unique modification

Une capture d'écran correspondant à StripsInterlacedLeftRight a donné :

Nom : binterlacedLeftRight.png
Affichages : 45
Taille : 288,0 Ko

Le travail similaire à effectuer pour des bandes verticales ne devrait pas nous poser de problèmes. Bien sûr, il faudra nous souvenir d'utiliser la largeur de l'image pour la calcul automatique des bandes. Voici le code nécessaire à la transition que nous nommerons StripsInterlacedDownUp :

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
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
procedure TMainForm.btnGoClick(Sender: TObject);
// *** dessin ***
var
  LBGRAFrom, LBGRATo, LBGRAMask: TBGRABitmap;
  LY, LX, LI, LStripWidth: Integer;
 
  function NumberOfStrips: Integer;
  const
    C_DefaultNumberOfStrips = 20;
  begin
    if imgResult.ClientWidth < 10 then
      Result := 1
    else
    if (imgResult.ClientWidth < 300) then
      Result := 5
    else
    if (imgResult.ClientWidth < 1000) then
      Result := imgResult.ClientWidth div C_DefaultNumberOfStrips
    else
      Result := 30;
  end;
 
begin
  btnGo.Enabled := False;
  LStripWidth := 1 + imgResult.ClientWidth div NumberOfStrips;
  LBGRAFrom := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
  try
    LBGRATo := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
    try
      LBGRAMask := TBGRABitmap.Create(imgResult.ClientWidth, ClientHeight, BGRABlack);
      try
        fStep := 0;
        repeat
          Inc(fStep);
          LX := 0;
          LY := 0;
          LBGRAFrom.FillRect(ClientRect, BGRABlack);
          LBGRAFrom.PutImage(LX, LY, fBGRAFrom, dmDrawWithTransparency, Opacity(False));
          for LI := 0 to NumberOfStrips do
            if Odd(LI) then
              LBGRAMask.FillRectAntialias(LStripWidth * LI,
                0, LStripWidth * (LI + 1),
                imgResult.ClientHeight * fStep div 100,
                BGRAWhite, False)
            else
              LBGRAMask.FillRectAntialias(LStripWidth * LI,
                imgResult.ClientHeight -  imgResult.ClientHeight * fStep div 100,
                  LStripWidth * (LI + 1),
                  imgResult.ClientHeight,
                  BGRAWhite, False);
          LBGRATo.PutImage(0, 0, fBGRATo, dmSet);
          LBGRATo.ApplyMask(LBGRAMask);
          LBGRAFrom.PutImage(0, 0, LBGRATo, dmDrawWithTransparency, Opacity);
          LBGRAFrom.Draw(imgResult.Canvas, 0, 0);
          imgResult.Repaint;
          sleep(100 - fSpeed);
        until fStep = 100;
      finally
        LBGRAMask.Free;
      end;
    finally
      LBGRATo.Free;
    end;
  finally
    LBGRAFrom.Free;
    btnGo.Enabled := True;
  end;
end;

Nous savons que, comme précédemment, sa sœur StripsInterlacedUpDown ne nécessitera qu'une inversion du résultat de la fonction Odd :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
for LI := 0 to NumberOfStrips do
            if not Odd(LI) then // unique modification

Voici une capture d'écran de StripsInterlacedDownUp à mi-parcours de son action :

Nom : binterlacedDownUp.png
Affichages : 53
Taille : 288,4 Ko

Encore un dernier effort avec les combinaisons de bandes et nous pourrons passer aux rotations et aux homothéties...

Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Viadeo Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Twitter Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Google Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Facebook Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Digg Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Delicious Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog MySpace Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite) » dans le blog Yahoo

Commentaires