Les transitions entre images sous Lazarus avec BGRABitmap (XXII) - Les transitions par bandes (suite)
par
, 14/05/2018 à 09h00 (1090 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 :
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é :
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 :
Encore un dernier effort avec les combinaisons de bandes et nous pourrons passer aux rotations et aux homothéties...