Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut Combiner zoom, rotation et transparence avec BGRABitmap

    Bonsoir,

    Je souhaite pouvoir effectuer tout à la fois un zoom, une rotation ou encore une transparence sur un graphique contenu dans un BGRABitmap.
    Le problème est que je ne parviens pas à associer les trois effets simultanément.

    Je suis parti du code suivant, inspiré d'une démo trouvé sur le forum anglais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TfrmMap.bgraMainRedraw(Sender: TObject; Bitmap: TBGRABitmap);
    begin
      Bitmap.PutImageAngle(Bitmap.Width/2-0.5, Bitmap.Height/2-0.5, bmp, tbAngle.Position, bmp.Width/2-0.5, bmp.Height/2-0.5, tbOpacity.Position);
    end;
    bmp est le graphique d'origine (taille: 1920x1080px) modifié et affiché dans Bitmap (taille: 856x624px).
    Le code ci-dessus effectue superbement une rotation avec transparence en prenant le centre de Bitmap comme axe de rotation.
    Mais je n'ai pas trouvé une procédure ou fonction qui permette en même temps de zoomer le graphique d'origine.

    Aussi j'ai modifié le code de la manière suivante :

    Code : 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
    procedure TfrmMap.bgraMainRedraw(Sender: TObject; Bitmap: TBGRABitmap);
    var
      affine: TBGRAAffineBitmapTransform;
      LBGRATemp: TBGRABitmap;
    begin
      LBGRATemp := TBGRABitmap.Create(bgraMain.ClientWidth, bgraMain.ClientHeight, BGRABlack);
      try
        affine := TBGRAAffineBitmapTransform.Create(bmp, false);
        affine.GlobalOpacity := tbOpacity.Position;
        affine.RotateDeg(tbAngle.Position);
        affine.Scale(tbZoom.Position / 100);
        affine.Translate(bgraMain.ClientWidth / 2, bgraMain.ClientHeight / 2); 
        LBGRATemp.Fill(affine);
        Bitmap.PutImage(0, 0, LBGRATemp, dmSet, tbOpacity.Position);             
      finally
        LBGRATemp.Free;
        affine.Free;
      end;
    end;
    Et là j'avais les trois effets (transparence, rotation et zoom) réunis ! Le hic toutefois, c'est que la rotation ne s'effectue plus à partir du centre de l'image !
    Quelle procédure ou fonction dois-je ajouter à la variable affine pour parvenir à ce résultat ?
    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 3 187
    Points : 9 176
    Points
    9 176
    Billets dans le blog
    1

    Par défaut

    Bonjour,

    Dans son tuto, Gilles utilise un code un peu différent : présente-t-il le même inconvénient ?
    Delphi 5 Pro - Delphi 10.2 Tokyo Community Edition - CodeTyphon 6.50 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 885
    Points : 2 451
    Points
    2 451
    Billets dans le blog
    2

    Par défaut

    Bonjour,
    je ne suis pas a la maison pour vérifier mais dans ton exemple tu as 4 étapes :

    Opacité --> Rotation --> Scale --> Translation

    Ton problème je pense est l'ordre des transformations. C'est important. Pour ma part je ferai comme ceci

    Scale --> Rotation --> Opacité --> (Translation si besoin)

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonsoir Tourlourou,

    Citation Envoyé par tourlourou Voir le message
    Gilles utilise un code un peu différent : présente-t-il le même inconvénient ?
    J'avais repéré hier la série de tutoriaux de Gilles Vasseur (au demeurant bienvenus) mais n'avais pas eu le temps de les étudier en profondeur.
    J'ai modifié la procédure principale de la façon suivante :

    Code : 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
     
      LBGRATemp := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
      try
        fStep := 0;
        ratio := round((imgResult.Width / imgTo.Picture.Width) * 100);
     
        repeat //
          Inc(fStep);
     
          // traitement ici...
          LX := imgResult.ClientWidth div 2;
          LY := imgResult.ClientHeight div 2;
          LBGRATemp.PutImageAngle(LX, LY, fBGRATo, fStep, fBGRATo.Width div 2, fBGRATo.Height div 2, Opacity);
          LBGRATemp.Draw(imgResult.Canvas, 0, 0);
          Application.ProcessMessages;
          sleep(100 - fSpeed);
     
          //inc(ratio);
          BGRAReplace(fBGRATo, fBGRATo.Resample(fBGRATo.Width + 2, fBGRATo.Height + 2));
          fBGRATo.StretchPutImage(fBGRATo.ClipRect, fBGRATest, dmSet);
          //until (ratio = 100);
          until (fStep = 360);
      finally
        LBGRATemp.Free;
        btnGo.Enabled := True;
      end;
    Tel quel, ce code redimensionne l'image d'origine (quel magnifique rouge-gorge !) tout en la faisant tourner par incrément d'un degré autour de son centre.
    L'incrément de 2 dans la procédure Resample est arbitraire. Il est censé être remplacé par un pourcentage de la taille originale de l'image.
    C'est dire que le code a encore besoin d'être amélioré !
    Merci pour ton aide.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonsoir BeanzMaster,

    Citation Envoyé par BeanzMaster Voir le message
    Ton problème je pense est l'ordre des transformations. C'est important. Pour ma part je ferai comme ceci :

    Scale --> Rotation --> Opacité --> (Translation si besoin)
    Merci de me faire profiter de ton expérience.
    Si je laisse de côté l'opacité qui n'est pas vraiment un problème, j'en suis venu à penser qu'il valait mieux tourner l'image en premier pour ne pas perdre les parties de cette image qui sont dans les coins !
    Après, il y a le problème de la "Translation" qui doit effectivement être considérée.
    Mais je ne suis qu'au début de ma découverte de TBGRABitmap qui me semble très prometteur.
    Merci beaucoup pour ton aide.

  6. #6
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 885
    Points : 2 451
    Points
    2 451
    Billets dans le blog
    2

    Par défaut

    Salut j'ai fait quelques recherche vite fait pour pouvoir effectuer un zoom et une rotation en même temps, regardes du coté de la fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
    procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
    procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte=255); overload;
    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); virtual; abstract; overload;
    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
    A l'aide des matrices tu pourras effectuer un zoom et une rotation
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonjour BeanzMaster,

    Merci pour ces quelques recherches. Je me suis essayé avec PutImageAffine, mais je n'ai pas trouvé comment faire pivoter l'image à partir de son centre durant "l'affinage".

    Code : 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
    procedure TfrmMap.bgraMainRedraw(Sender: TObject; Bitmap: TBGRABitmap);
    var
      LBGRATemp: TBGRABitmap;
      percent, ratio: single;
    begin
      percent := (LBGRABase.Width / Bitmap.Width) / 100;
      ratio := tbZoom.Position * percent;
      LBGRATemp := TBGRABitmap.Create(LBGRABase.Width, LBGRABase.Height, BGRAWhite);
      try
        LBGRATemp.PutImageAffine(AffineMatrixScale(ratio, ratio) *
                                 AffineMatrixRotationDeg(tbAngle.Position),
                                 LBGRABase, tbOpacity.Position);
        LBGRATemp.Draw(Bitmap.Canvas, 0, 0);
      finally
        LBGRATemp.Free;
      end;
    end;

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonsoir BeanzMaster,

    Citation Envoyé par Péhelji
    J'en suis venu à penser qu'il valait mieux tourner l'image en premier pour ne pas perdre les parties de cette image qui sont dans les coins !
    Je suis venu à bout de ce problème et à combiner les trois effets avec la procédure suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
      offsetX := round(((tbZoom.Position - 100) * LBGRABase.Width  div 2) / 100);
      offsetY := round(((tbZoom.Position - 100) * LBGRABase.Height div 2) / 100);
     
      LBGRATemp := TBGRABitmap.Create(LBGRABase.Width, LBGRABase.Height);
      try
        LBGRATemp.PutImageAngle(LBGRATemp.Width/2-0.5, LBGRATemp.Height/2-0.5, LBGRABase, tbAngle.Position,
                                LBGRABase.Width/2-0.5, LBGRABase.Height/2-0.5, tbOpacity.Position);
        rc := LBGRATemp.ClipRect;
        rc.Inflate(round(offsetX), round(offsetY));
     
        Bitmap.Canvas.CopyRect(Bitmap.ClipRect, LBGRATemp.Canvas, rc);
      finally
        LBGRATemp.Free;
      end;
    Peut-être serait-il possible d'améliorer la fluidité du zoom en utilisant BGRAVirtualScreen ou encore BGRACanvas2D ?

    J'ai trouvé de quoi plancher sur le sujet avec la démo LayerOriginal fournie avec BGRABitmap, et aussi celle postée ici par Circular.

  9. #9
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 885
    Points : 2 451
    Points
    2 451
    Billets dans le blog
    2

    Par défaut

    Salut,

    je n'ai pas beaucoup de temps en ce moment et je n'utilise que très rarement BGRABitmap mais, pour ce qui est de la fluidité lis les tutoriels de Gilles,. Tu n'as pas vraiment besoin du BGRAVirtualScreen.
    Le BGRACanvas2D c'est comme le TCanvas donc pas besoin dans ton cas.

    Voila comment à fait Gilles pour la rotation et le zoom :

    Code : 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
    procedure TGVTransition.DoGrowCenterRotate(CCW: Boolean);
    // *** GrowCenterCCWRotate et GrowCenterCWRotate ***
    var
      LBGRATemp: TBGRABitmap;
    begin
      LBGRATemp := fLBGRATo.Resample(
        ComputeInterpolationInt(C_MinResample, ClientWidth),
        ComputeInterpolationInt(C_MinResample, ClientHeight)) as TBGRABitmap;
      try
        fLBGRAFrom.PutImageAngle(ClientWidth / 2, ClientHeight / 2, LBGRATemp,
          ifthen(CCW, ComputeInterpolation(360, 0), ComputeInterpolation(-360, 0)),
          LBGRATemp.Width / 2, LBGRATemp.Height / 2,DestinationOpacity);
      finally
        LBGRATemp.Free;
      end;
    end;
    Moins de calcul déja ici

    Petite question que souhaites tu réaliser au final ? Une animation ? un mini-éditeur ?

    https://gilles-vasseur.developpez.co...sitions/bgra1/
    https://gilles-vasseur.developpez.co...sitions/bgra2/
    https://gilles-vasseur.developpez.co...sitions/bgra3/
    https://gilles-vasseur.developpez.co...sitions/bgra4/
    https://gilles-vasseur.developpez.co...sitions/bgra5/
    https://gilles-vasseur.developpez.co...sitions/bgra6/
    https://gilles-vasseur.developpez.co...sitions/bgra7/
    https://gilles-vasseur.developpez.co...sitions/bgra8/
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonjour BeanzMaster,

    J'ai téléchargé les tutoriels de Gilles et j'ai testé les démos et le test simple livré avec le tutoriel n°8. C'est pour le moins bluffant !
    C'est effectivement vers les transitions GrowCenter et GrowCenterCWRotate que je dois rechercher la solution à mon problème.
    Quoique j'étais parvenu à une meilleure fluidité avec la séquence suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      LBGRATemp := TBGRABitmap.Create(LBGRABase.Width, LBGRABase.Height{, BGRAWhite});
      try
        LBGRATemp.PutImageAffine(
          AffineMatrixScale(ratio, ratio) *
          AffineMatrixTranslation(LBGRABase.Width/2-0.5, LBGRABase.Height/2-0.5) *
          AffineMatrixRotationDeg(tbAngle.Position) *
          AffineMatrixTranslation(-LBGRABase.Width/2-0.5, -LBGRABase.Height/2-0.5),
          LBGRABase, tbOpacity.Position);
        LBGRATemp.Draw(Bitmap.Canvas, 0, 0);
      finally
        LBGRATemp.Free;
      end;
    La rotation est nickel au centre du canvas... mais le zoom n'opère qu'à partir du coin supérieur gauche !
    Le nœud du problème se situe au niveau des paramètres passés à AffineMatrixTranslation. Je vais voir si les fonctions ComputeInterpolation des tutos ne seraient pas la solution.

    Citation Envoyé par BeanzMaster Voir le message
    Petite question que souhaites tu réaliser au final ? Une animation ? un mini-éditeur ?
    Je travaille sur une application de cartographie et, dans un premier temps, je souhaite pouvoir ajuster des cartes de différentes tailles en les superposant (j'ai testé BGRALayers), chaque couche devant être modifiable par zoom, rotation, transparence et bien entendu déplacement.
    Merci encore pour ta recherche et tes conseils.

  11. #11
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 885
    Points : 2 451
    Points
    2 451
    Billets dans le blog
    2

    Par défaut

    Bonsoir

    Utiliser des calques sera en effet la solution. Mais je ne comprends pas bien ton désir de vouloir faire un zoom et une rotation en même temps. Le problème dans ta translation vient du fait que tu redimensionnes ton image, du coup la largeur et la hauteur ne sont par conséquent plus les mêmes que LBGRABase.

    Je ne sais pas si j'aurai assez de temps cette semaine et jusqu'après les fêtes. Mais je tenterai quelque chose si je peux.

    Bonne fin de soirée.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  12. #12
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 885
    Points : 2 451
    Points
    2 451
    Billets dans le blog
    2

    Par défaut

    Salut, j'ai eu un peu de temps aujourd'hui (j'en avais marre de ce que je faisait du coup...)

    La fonction PutAffine n'est pas l'idéal, ou sinon il faudrait procéder en 2 étapes (Zoom + Rotation puis une translation).

    Voilà le code à l'arrache que j'ai fait. Il devrait correspondre à ce que tu recherches.

    Code : 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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
      ExtDlgs, BGRABitmapTypes, BGRABitmap; //, BGRATransform;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        Button1: TButton;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        OpenPictureDialog1: TOpenPictureDialog;
        Panel1: TPanel;
        ScrollBar1: TScrollBar;
        ScrollBar2: TScrollBar;
        ScrollBar3: TScrollBar;
        ScrollBar4: TScrollBar;
        ScrollBar5: TScrollBar;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Panel1Paint(Sender: TObject);
        procedure ScrollBar1Change(Sender: TObject);
      private
        DisplayBuffer : TBGRABitmap;
        SrcBitmap : TBGRABitmap;
     
      public
        procedure RotateAndZoom(Ratio:Single; Angle : Single; Opacity : Byte);
     
     
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      DisplayBuffer := TBGRABitmap.Create(Panel1.ClientWidth, Panel1.ClientHeight);
      SrcBitmap := TBGRABitmap.Create;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if openPictureDialog1.Execute then
      begin
        SrcBitmap.LoadFromFile(OpenPictureDialog1.FileName);
        DisplayBuffer.PutImage(0,0,SrcBitmap,dmDrawWithTransparency,255);
        Panel1.Invalidate;
      end;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      FreeAndNil(DisplayBuffer);
      FreeAndNil(SrcBitmap);
    end;
     
    procedure TForm1.Panel1Paint(Sender: TObject);
    begin
      DisplayBuffer.Draw(Panel1.Canvas,0,0);
    end;
     
    procedure TForm1.ScrollBar1Change(Sender: TObject);
    begin
      DisplayBuffer.Canvas.Clear;
      RotateAndZoom(Scrollbar1.position / 100, Scrollbar2.Position, ScrollBAr3.Position);
      Panel1.Invalidate;
    end;
     
    procedure TForm1.RotateAndZoom(Ratio: Single; Angle: Single; Opacity : Byte);
    var
      LBGRATemp: TBGRABitmap;
      LNewWidth, LNewHeight, LMidWidth, LMidHeight : Integer;
    begin
      LNewWidth := round(SrcBitmap.Width * ratio);
      LNewHeight := round(SrcBitmap.Height * ratio);
      LMidWidth := LNewWidth shr 1;
      LMidHeight := LNewHeight shr 1;
      LBGRATemp := SrcBitmap.Resample(LNewWidth, LNewHeight) as TBGRABitmap;
      try
         DisplayBuffer.PutImageAngle(LMidWidth + ScrollBar4.Position, LMidHeight + ScrollBar5.Position, LBGRATemp,
          Angle,
          LMidWidth, LMidHeight,Opacity);
      finally
        LBGRATemp.Free;
      end;
    end;
     
    end.
    Un simple array ou un TList avec un record genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TBitmapLayer = record
      OriginalBitmap : TBGRABitmap;
      OffsetX, OffsetY : Integer;
      Angle : Integer;
      ZoomRatio : Single;
    end;
    devrait faire l'affaire pour gérer tes calques.

    Bonne soirée.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    janvier 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Service public

    Informations forums :
    Inscription : janvier 2018
    Messages : 29
    Points : 5
    Points
    5

    Par défaut

    Bonjour BeanzMaster,

    Citation Envoyé par BeanzMaster
    Je ne sais pas si j'aurai assez de temps cette semaine et jusqu'après les fêtes. Mais je tenterai quelque chose si je peux.
    (...)
    Salut, j'ai eu un peu de temps aujourd'hui.
    D'abord merci de m'avoir accordé ce peu de temps pour "pondre" un code qui est fonctionnel dans le principe (je viens de le tester) et pardon d'avoir tardé à te répondre, mais d'une part j'ai moi-même été assez pris la semaine passée et, d'autre part, vas-t-en savoir pourquoi, je n'ai pas reçu du forum la moindre notification de tes deux derniers messages !

    Dans l'intervalle, après avoir étudié les tutos de Gilles, je me suis aperçu que mon code initial n'était pas si mauvais que çà et qu'il demandait juste à être affiné.
    Et je suis arrivé à un rendu qui me convient avec la fonction suivante :

    Code : 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
     
    var
      BGRATemp: TBGRABitmap;
      BitmapRect, BGRATempRect: TRect;
      offsetX, offsetY: single;
    begin
      BitmapRect := Bitmap.ClipRect;
     
      BGRATemp := TBGRABitmap.Create(BGRABase.Width, BGRABase.Height);
      BGRATempRect := BGRATemp.ClipRect;
      try
        BGRATemp.PutImageAngle(BGRATemp.Width / 2 - 0.5, BGRATemp.Height / 2 - 0.5,
                               BGRABase, tbAngle.Position,
                               BGRABase.Width / 2 - 0.5, BGRABase.Height / 2 - 0.5,
                               tbOpacity.Position);
     
        offsetX := (BGRABase.Width / tbZoom.Position) * 100 * ratioX;
        offsetX := (BGRABase.Width - offsetX) / 2;
        offsetY := (BGRABase.Height / tbZoom.Position) * 100 * ratioY;
        offsetY := (BGRABase.Height - offsetY) / 2;
     
        if (offsetX < 0) or (offsetY < 0) then
           begin
             offsetX := (tbZoom.Position * Bitmap.Width) / 100 / ratioX;
             offsetX := (Bitmap.Width - offsetX) / 2;
             offsetY := (tbZoom.Position * Bitmap.Height) / 100 / ratioY;
             offsetY := (Bitmap.Height - offsetY) / 2;
             BitmapRect.Inflate(-round(offsetX), -round(offsetY));
           end else
             BGRATempRect.Inflate(-round(offsetX), -round(offsetY));
     
        Bitmap.Canvas.CopyRect(BitmapRect, BGRATemp.Canvas, BGRATempRect);
      finally
        BGRATemp.Free;
      end;
    end;
    Cela peut paraître beaucoup de calcul mais se justifie pour afficher l'image au centre du contrôle fenêtré, et ce quelque soit le zoom ou l'angle considéré, une condition essentielle que ton merveilleux petit bout de code fait "à l'arrache" ne prends pas en compte . En le compilant, je me suis aperçu de la lenteur du processus quand il s'agit d'effectuer un zoom ou une rotation sur une image de 3400x3400px (qui me sert d'étalon pour mes tests), ce qui ne pose aucun problème au code ci-dessus . D'autant que plusieurs images, superposées, doivent pouvoir être modifiées indépendamment les unes des autres ou simultanément !

    Citation Envoyé par BeanzMaster
    Je ne comprends pas bien ton désir de vouloir faire un zoom et une rotation en même temps.
    En fait, je me suis mal exprimé. Ce que je voulais dire, c'est qu'au final, le rendu devait tenir compte des trois effets recherchés, même si chacun était actionné indépendamment, ce que tu as très bien réalisé en utilisant des Scrollbars (tout comme moi-même j'utilisais des Trackbars, mais le principe est le même).

    Si tu ne vois rien à rajouter, peut-être pourrais-tu m'indiquer si c'est à moi d'activer la balise "Résolu", puisque j'estime qu'au travers de tes réponses tu as solutionné ma difficulté du départ.
    Encore merci à toi.

Discussions similaires

  1. [D5] Zoom d'image PNG avec transparence
    Par Thierry Laborde dans le forum Delphi
    Réponses: 9
    Dernier message: 12/06/2006, 16h41
  2. Réponses: 13
    Dernier message: 01/12/2005, 06h34
  3. Texte en transparence avec TextOut
    Par TigreRouge dans le forum MFC
    Réponses: 2
    Dernier message: 06/06/2005, 23h57
  4. [Rotations] Rotations Locales/Globales avec Quaternions
    Par Clorish dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 24/05/2005, 17h41
  5. probleme de transparence avec fog
    Par Daedar dans le forum OpenGL
    Réponses: 10
    Dernier message: 03/05/2004, 09h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo