Voir le flux RSS

Blog de Gilles Vasseur - Pascal et compagnie

Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite)

Noter ce billet
par , 12/04/2018 à 21h56 (264 Affichages)
Nous avons vu dans le précédent billet comment utiliser les formes géométriques, soit seules, soit combinées avec d'autres.

Évidemment, nous pouvons compliquer à loisir nos transitions, même à partir de figures simples comme les triangles, afin d'obtenir des transitions vraiment spectaculaires. Dans la portion de code qui suit, nous définissons une surface composée de nouveau de quatre triangles, mais en suivant les données et règles suivantes :

  • un triangle isocèle dont chaque sommet au départ de la transition est à une distance d'un tiers des bords de l'image de travail (sa hauteur vaut donc un tiers de la hauteur de l'image tandis que sa base vaut un tiers de la largeur de la même image) ;



Nom : megastar1.png
Affichages : 24
Taille : 6,2 Ko

  • un autre triangle isocèle de même taille, mais tête-bêche par rapport au premier, placé de telle manière que ses sommets aient la même abscisse que les sommets du premier alors que ses ordonnées sont décalées vers le bas l'image pour que l'intersection des côtés passe par le milieu de la hauteur de l'image ;



Nom : megastar2.png
Affichages : 23
Taille : 7,1 Ko

  • un triangle dont deux sommets ont toujours comme coordonnées le point supérieur gauche et le point inférieur gauche de l'image tandis que le troisième sommet toujours à mi-hauteur se déplacera du bord gauche de l'image vers le premier quart de l'image sur sa droite (sa base est donc sur le côté gauche de l'image tandis que ses deux autres côtés suivent sa médiatrice) ;



Nom : megastar3.png
Affichages : 22
Taille : 6,9 Ko

  • un triangle dont deux sommets ont toujours comme coordonnées le point supérieur droit et le point inférieur droit de l'image tandis que le troisième sommet toujours à mi-hauteur se déplacera du bord droit de l'image vers le dernier quart de l'image sur sa gauche dans la même proportion que le triangle précédent (il est donc le symétrique du triangle précédent par rapport au milieu de la largeur de l'image).



Nom : megastar4.png
Affichages : 23
Taille : 8,1 Ko

L'évolution de chacun des points définis est telle que l'étoile formée par les deux triangles tête-bêche doit se dilater, les deux autres triangles s'approchant d'elle jusqu'à la rejoindre.

Le code proposé est le suivant :

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
69
70
71
72
73
74
75
procedure TMainForm.btnGoClick(Sender: TObject);
// *** dessin ***
var
  LBGRAFrom, LBGRATo, LBGRAMask: TBGRABitmap;
  LY, LX: Integer;
  LPts: array of TPointF;
begin
  btnGo.Enabled := False;
  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;
        SetLength(LPts, 3);
        repeat
          Inc(fStep);
          // traitement 1 ici (source)
          LX := 0;
          LY := 0;
          LBGRAFrom.FillRect(ClientRect, BGRABlack);
          LBGRAFrom.PutImage(LX, LY, fBGRAFrom, dmDrawWithTransparency, Opacity(False));
          // traitement 2 ici (destination)...
          // premier triangle
          LBGRAMask.FillRectAntialias(0, 0, imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
          LPts[0].x := imgResult.ClientWidth / 3 - imgResult.ClientWidth / 3 * fStep / 100;
          LPts[0].y := imgResult.ClientHeight / 3 * 2 + imgResult.ClientHeight / 3 * fStep / 100;
          LPts[1].x := imgResult.ClientWidth / 2;
          LPts[1].y := imgResult.ClientHeight / 3 - imgResult.ClientHeight / 3 * fStep / 100;
          LPts[2].x := imgResult.ClientWidth / 3 * 2 + imgResult.ClientWidth / 3 * fStep / 100;
          LPts[2].y := LPts[0].y;
          LBGRAMask.FillPolyAntialias(LPts, BGRAWhite);
          // triangle opposé
          //LPts[0].x := imgResult.ClientWidth / 3 - imgResult.ClientWidth / 3 * fStep / 100;
          LPts[0].y := imgResult.ClientHeight / 2 - imgResult.ClientHeight / 2 * fStep / 100;
          LPts[1].x := imgResult.ClientWidth / 3 * 2 + imgResult.ClientWidth / 3 * fStep / 100;
          LPts[1].y := LPts[0].y;
          LPts[2].x := imgResult.ClientWidth / 2;
          LPts[2].y := imgResult.ClientHeight / 6 * 5 + imgResult.ClientHeight / 6 * fStep / 100;
          LBGRAMask.FillPolyAntialias(LPts, BGRAWhite);
          // triangle côté gauche
          LPts[0].x := 0;
          LPts[0].y := 0;
          LPts[1].x := imgResult.ClientWidth / 4 * fStep / 100;
          LPts[1].y := imgResult.ClientHeight / 2;
          LPts[2].x := LPts[0].x;
          LPts[2].y := imgResult.ClientHeight;
          LBGRAMask.FillPolyAntialias(LPts, BGRAWhite);
          //triangle côté droit
          LPts[0].x := imgResult.ClientWidth;
          //LPts[0].y := 0;
          LPts[1].x := imgResult.ClientWidth - imgResult.ClientWidth / 4 * fStep / 100;
          //LPts[1].y := imgResult.ClientHeight / 2;
          LPts[2].x := LPts[0].x;
          //LPts[2].y := imgResult.ClientHeight;
          LBGRAMask.FillPolyAntialias(LPts, BGRAWhite);
          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;

Dans le code qui précède, certaines lignes de code ont été neutralisées par leur mise en commentaire : il s'agit de lignes qui aident à comprendre les calculs effectués, mais qui sont superflues puisque les bonnes valeurs sont déjà attribuées aux variables visées.

L'effet produit, nommé MegaStar, est plutôt spectaculaire et original. La vidéo suivante tente d'en rendre compte :


Dans les exemples donnés, nous nous sommes limités aux triangles, mais rien ne nous interdit de créer des polynômes plus complexes. De plus, les masques peuvent être composites en intégrant toutes les formes imaginables (par exemple*: deux rectangles, une ellipse et un octogone) dans la mesure où l'image de destination aura remplacé à la fin de la transition la totalité de l'image d'origine.

À l'occasion du travail proposé par les derniers billets, outre la richesse de FillRectAntialias, vous aurez aussi découvert de nouvelles méthodes de la classe TBGRABitmap comme ApplyMask, FillEllipseAntialias ou FillPolyAntialias (qui s'appuie sur les enregistrements de type TPointF). Votre boîte à outils s'est par conséquent bien étendue.

Par la suite, nous multiplierons les occasions d'utiliser des masques, abandonnant ainsi définitivement les premières solutions adoptées. Une prochaine étape nous verra utiliser les couches à travers une classe différente de TBGRABitmap...

Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Viadeo Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Twitter Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Google Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Facebook Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Digg Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Delicious Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog MySpace Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (XVI) - Utilisation des formes géométriques (suite) » dans le blog Yahoo

Commentaires