Les transitions entre images sous Lazarus avec BGRABitmap (XX) - Les transitions par bandes
par
, 09/05/2018 à 22h20 (1048 Affichages)
Certaines transitions répètent un motif sur la zone d'affichage. Afin d'illustrer ce cas, nous allons construire une série de transitions qui dessineront des rectangles régulièrement espacés pour faire apparaître l'image de destination. L'espacement sera vertical ou horizontal.
Les transitions par bandes
Les bandes horizontales
Il s'agit dans un premier temps de produire des bandes horizontales. Le principe est de diviser la hauteur de l'image par le nombre de bandes et de commencer à dessiner l'image de destination depuis les points ainsi trouvés. Chaque bande (rectangle) commencera à un point et ira jusqu'au point suivant (vers le haut ou vers le bas) en suivant le rythme des étapes, donc de 0 à 100.
La transition StripsDown nous servira de modèle.
Son schéma de fonctionnement avec un calque sera celui-ci :
Pour nos essais, nous déclarerons une constante C_NumberOfStrips qui fournira le nombre de bandes à dessiner. Comme pour les points de la spline, nous envisagerons ultérieurement le choix de ce nombre par l'utilisateur lui-même.
Grâce à cette constante, nous pourrons calculer aisément l'ordonnée de départ de chacune des bandes. Les abscisses sont par ailleurs déjà connues puisque les bandes occuperont en permanence toute la largeur de l'image.
La hauteur de l'image est quelconque si bien que nous pourrions nous heurter à deux problèmes. Le premier proviendrait du fait que la hauteur ne serait pas exactement divisible par le nombre de bandes si bien qu'il nous faudrait en tenir compte afin de bien recouvrir toute la surface de l'image : nous prévoirons systématiquement une bande supplémentaire pour éviter ce problème potentiel. Bien que peu probable, le second problème surgirait si la hauteur était plus petite en pixels que le nombre de bandes : ce cas ne sera pas traité pour le moment, mais nous devrons le garder en tête.
Pour rendre les calculs plus clairs, nous définirons aussi une variable locale LStripHeight qui contiendra la hauteur de la bande en fonction du nombre de bandes et de la hauteur de l'image.
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
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 procedure TMainForm.btnGoClick(Sender: TObject); // *** dessin *** const C_NumberOfStrips = 10; var LBGRAFrom, LBGRATo, LBGRAMask: TBGRABitmap; LY, LX, LI, LStripHeight: Integer; begin btnGo.Enabled := False; // calcul de la hauteur d'une bande + 1 pour les arrondis LStripHeight := 1 + imgResult.ClientHeight div C_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)); // nous traçons les bandes for LI := 0 to C_NumberOfStrips - 1 do begin // chaque bande est un rectangle LBGRAMask.FillRectAntialias(0, LStripHeight * LI, imgResult.ClientWidth, LStripHeight * fStep div 100 + LStripHeight * LI, BGRAWhite); end; 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;
Le code ressemble beaucoup à ce qui a déjà été étudié. Une copie instantanée d'écran a donné :
La réciproque de cette transition sera appelée StripsUp. Sans surprise, le cœur du code nécessaire sera :
Très bientôt, nous verrons les bandes verticales. Vous devriez trouver sans peine comment les implémenter !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 for LI := 1 to C_NumberOfStrips do begin LBGRAMask.FillRectAntialias(0, LStripHeight * LI - LStripHeight * fStep div 100, imgResult.ClientWidth, LStripHeight * LI, BGRAWhite); end;