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
    Responsable Delphi

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    février 2013
    Messages
    1 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 1 339
    Points : 17 591
    Points
    17 591
    Billets dans le blog
    73

    Par défaut Apprendre à créer des transitions d'image à image avec Lazarus et BGRABitmap (1)

    Apprendre à créer des transitions d'image à image
    Avec Lazarus et BGRABitmap


    Bonjour à toutes et à tous !


    La série de tutoriels inaugurée par celui que vous allez lire est destinée au programmeur soucieux d'exploiter au mieux le graphisme avec Lazarus, mais peut-être aussi à celui qui souhaite découvrir ou collecter des algorithmes pour créer des transitions d'image à image, par exemple pour un diaporama.

    Les explications s'appuient sur Free Pascal et la bibliothèque BGRABitmap, tous deux des outils gratuits, open source et multiplateformes qui ont fait leurs preuves, mais elles ne se limitent pas à une illustration de leurs fonctionnalités : les techniques et les raisonnements utilisés devraient être suffisamment commentés pour être exploités par des utilisateurs d'autres langages et d'autres bibliothèques graphiques. Si vous faites partie de cette catégorie de lecteurs, c'est à partir du deuxième tutoriel que vous devriez trouver votre compte, celui en cours expliquant comment installer la bibliothèque et posant les bases d'une application de démonstration.

    Si vous utilisez déjà Lazarus, sachez que ce qui va être présenté est compilable sans la moindre modification aussi bien sous Windows que sous Linux, en 32 ou 64 bits.

    Pour illustrer le résultat final de la série, à savoir un composant prêt à l'emploi, voici une vidéo qui le montre en action :



    Pour lire le tutoriel, c'est ici : https://gilles-vasseur.developpez.co...sitions/bgra1/

    Que pensez-vous de ce tutoriel ?
    Quelle utilisation faites-vous du graphisme avec Lazarus ?

    Retrouvez les meilleurs cours et tutoriels pour apprendre la programmation avec Lazarus.
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

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

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Bonjour

    Intéressant comme article Gilles, j'ai hâte de lire la suite . Une seule remarque j'ai testé l'exemple 3, sous Windows c'est très fluide, mais sous Linux c'est d'une lenteur déconcertante A vérifier si c'est juste chez moi ou pas. Pour informations je dispose des même version Lazarus et de BGRABitmap sous mes 2 plateformes.

    A Bientôt
    • "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

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    7 219
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 7 219
    Points : 10 280
    Points
    10 280

    Par défaut

    Citation Envoyé par BeanzMaster Voir le message
    j'ai testé l'exemple 3, sous Windows c'est très fluide, mais sous Linux c'est d'une lenteur déconcertante
    Linux en MV ? Si oui, je l'ai remarqué aussi avec d'autres projets : dans le host Linux le projet va très bien, et dans une MV Linux (où j'ai la dernière version de Laz/Fpc) ça rame d'une manière impressionnante.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Responsable Delphi

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    février 2013
    Messages
    1 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 1 339
    Points : 17 591
    Points
    17 591
    Billets dans le blog
    73

    Par défaut

    Citation Envoyé par BeanzMaster Voir le message
    Une seule remarque j'ai testé l'exemple 3, sous Windows c'est très fluide, mais sous Linux c'est d'une lenteur déconcertante
    Comme Jipété l'a écrit ci-dessus, il semblerait que ce soit sur les machines virtuelles que se pose le problème. Avec une mémoire réservée au graphisme souvent ridicule, ce n'est pas forcément étonnant. Mais il y a peut-être d'autres raisons, car voici le composant en action sous Linux Ubuntu Studio avec Oracle VM VirtualBox à jour :




    On voit que les transitions sont plutôt rapides (à vrai dire, la boucle comporte 72 pas, mais la différence avec 100 n'est pas considérable), mais qu'il y a parfois un petit problème en fin de transition (un freeze bref mais visible).

    J'attends confirmation de la source du problème !

    Gilles
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  5. #5
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    7 219
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 7 219
    Points : 10 280
    Points
    10 280

    Par défaut

    Citation Envoyé par gvasseur58 Voir le message
    Avec une mémoire réservée au graphisme souvent ridicule, ce n'est pas forcément étonnant.
    OMG tu as surement raison : dans mes MV, pour ne pas pomper les ressources du host, je n'attribue en général que 64 à 128 Mo.
    Promis, la prochaine machine je l'achète avec 16 Go minimum (là je n'ai que 4).


    -- Un aparté purement esthétique --

    Je sais bien que les machines peuvent tout faire, mais est-il alors nécessaire de tout faire puis tout montrer ?

    Je ne parle pas de ta démo, qui est une démo, justement, mais c'est elle qui me met la puce à l'oreille et la larme à l'œil.
    On ne voit plus que ça partout à la téloche, maintenant, et ça se répand à toute allure, le moindre petit sujet devient un calvaire visuel et sonore :
    entre les transitions d'un plan à l'autre à coups d'effets parasite, flash de couleurs, tournage de pages, déformations d'image, et le rajout de bruits pour accentuer, bien marquer l'effet visuel, passer du temps devant cet appareil devient une torture audio-visuelle.

    Juste parce que les nouvelles consoles de montage permettent ces effets ? Mais à part du brouillage visuel et de la pollution sonore, ces ajouts n'apportent rien.

    C'est Saint-Ex' qui disait
    Citation Envoyé par Saint-Ex'
    La perfection, ce n'est pas quand il n'y a plus rien à rajouter, c'est quand il n'y a plus rien à enlever.
    Donc virez-nous tous ces effets de transitions et les documentaires gagneront en lisibilité et et fluidité du message passé.

    Sur Arte ils s'amusent même à utiliser des polices pourries, pour perdre en lisibilité : on marche sur la tête, là ! Une police est là pour qu'on puisse bien lire le message qu'elle a à transmettre et surtout, qu'elle se fasse oublier.
    Les graveurs de caractères depuis 500 ans doivent se retourner dans leur tombe et maudire ces machines modernes et les imbéciles incultes qui les utilisent si mal, s'imaginant que puisqu'on peut tout faire alors il faut tout faire, même si c'est du grand n'importe quoi.

    À croire que les mecs ne regardent pas les documents qu'ils produisent...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Citation Envoyé par gvasseur58 Voir le message
    Comme Jipété l'a écrit ci-dessus, il semblerait que ce soit sur les machines virtuelles que se pose le problème. Avec une mémoire réservée au graphisme souvent ridicule, ce n'est pas forcément étonnant. Mais il y a peut-être d'autres raisons, car voici le composant en action sous Linux Ubuntu Studio avec Oracle VM VirtualBox à jour :


    On voit que les transitions sont plutôt rapides (à vrai dire, la boucle comporte 72 pas, mais la différence avec 100 n'est pas considérable), mais qu'il y a parfois un petit problème en fin de transition (un freeze bref mais visible).

    J'attends confirmation de la source du problème !

    Gilles
    Bonjour malheureusement ce n'est pas une MV.

    Mon système Linux :
    Manjaro avec KDE et carte graphique NVidia GTX 1070 8Go et tous les drivers sont parfaitement installés

    Je n'ai pas testé d'autres projets utilisant BGRABitmap mais le problème vient surement de lui. Avec le projet sur lequel je travaille actuellement j'ai un perte de vitesse sous Linux de l'ordre de 4/5 fps comparé à Windows pour un affichage d'un bitmap dans une fenêtre en 1024x768. C'est à dire pas grand chose. Avec BGRABitmap et ton exemple je peux compter les minutes. Donc serait ce dût à l'utilisation de KDE ? j'en doute

    Je vais faire d'autre test avec BGRABitmap je te tiens au courant.

    Jérôme
    • "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
    Membre émérite
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Me revoilà, le coupable c'est le TImage. En le remplaçant par un simple TPanel c'est tout bon la vitesse est identique à Windows

    Voici les changements que j'ai effectué :

    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
    type
     
      { TMainForm }
     
      TMainForm = class(TForm)
        btnGo: TButton;
        cbOpacity: TCheckBox;
        imgFrom: TImage;
        imgTo: TImage;
        lblSpeed: TLabel;
        imgResult: TPanel; // Remplacement du TImage
        tbarSpeed: TTrackBar;
        procedure btnGoClick(Sender: TObject);
        procedure cbOpacityChange(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure imgResultPaint(Sender: TObject);
        procedure tbarSpeedChange(Sender: TObject);
      private
        fBGRAFrom, fBGRATo: TBGRABitmap;
        LBGRATemp: TBGRABitmap; // Ajout du tampon pour l'animation
        fSpeed: Byte;
        fStep: Byte;
        fWithOpacity: Boolean;
        procedure SetSpeed(AValue: Byte);
        procedure SetWithOpacity(AValue: Boolean);
      public
        function Opacity(Up: Boolean = True): Byte;
        property Speed: Byte read fSpeed write SetSpeed default C_DefaultSpeed;
        property WithOpacity: Boolean read fWithOpacity write SetWithOpacity;
      end;    
     
    procedure TMainForm.btnGoClick(Sender: TObject);
    // *** dessin ***
    var
     
      LY, LX: Integer;
    begin
      btnGo.Enabled := False;
     
      try
        LX := 0;
        LY := 0;
        fStep := 0;
        repeat
          Inc(fStep);
          LBGRATemp.FillRect(ClientRect, BGRABlack);
          LBGRATemp.PutImage(0, 0, fBGRAFrom, dmSet, Opacity(False));
          // traitement ici...
         // LY := - imgResult.ClientHeight + imgResult.ClientHeight * fStep div 100; // OVERDOWN
          LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);
          imgResult.Repaint;
          Application.ProcessMessages; // Envoi du message pour redessiner le TPanel imgResult
          sleep(100 - fSpeed);
        until fStep = 100;
      finally
       //
        btnGo.Enabled := True;
      end;
    end;
     
    procedure TMainForm.FormCreate(Sender: TObject);
    // *** construction des objets de travail ***
    begin
      Caption := rsTestName;
      fBGRAFrom := TBGRABitmap.Create(imgFrom.Picture.Bitmap);
      BGRAReplace(fBGRAFrom, fBGRAFrom.Resample(imgResult.ClientWidth, imgResult.ClientHeight));
      fBGRATo := TBGRABitmap.Create(imgTo.Picture.Bitmap);
      BGRAReplace(fBGRATo, fBGRATo.Resample(imgResult.ClientWidth, imgResult.ClientHeight));
      fSpeed := C_DefaultSpeed;
      tbarSpeed.Position:= Speed;
      LBGRATemp := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack); // Creation du tampon
    end;
     
    procedure TMainForm.FormDestroy(Sender: TObject);
    // *** destruction des objets de travail ***
    begin
      fBGRAFrom.Free;
      fBGRATo.Free;
      LBGRATemp.Free; // Liberation du tampon
    end;
     
    procedure TMainForm.imgResultPaint(Sender: TObject);
    begin
        LBGRATemp.Draw(imgResult.Canvas, 0, 0); // Transfert du tampon à la surface d'affichage
    end;
    • "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

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

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Le mieux serait de passer par un timer, et plus besoin du OnPaint du TPanel

    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
    type
     
      { TMainForm }
     
      TMainForm = class(TForm)
        btnGo: TButton;
        cbOpacity: TCheckBox;
        imgFrom: TImage;
        imgTo: TImage;
        lblSpeed: TLabel;
        imgResult: TPanel;
        tbarSpeed: TTrackBar;
        Timer1: TTimer;
        procedure btnGoClick(Sender: TObject);
        procedure cbOpacityChange(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure tbarSpeedChange(Sender: TObject);
        procedure Timer1StartTimer(Sender: TObject);
        procedure Timer1StopTimer(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        fBGRAFrom, fBGRATo: TBGRABitmap;
        LBGRATemp: TBGRABitmap;
        LY, LX: Integer;
        fSpeed: Byte;
        fStep: Byte;
        fWithOpacity: Boolean;
        procedure SetSpeed(AValue: Byte);
        procedure SetWithOpacity(AValue: Boolean);
      public
        function Opacity(Up: Boolean = True): Byte;
        property Speed: Byte read fSpeed write SetSpeed default C_DefaultSpeed;
        property WithOpacity: Boolean read fWithOpacity write SetWithOpacity;
      end;
    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
    procedure TMainForm.btnGoClick(Sender: TObject);
    // *** dessin ***
    begin
      Timer1.Interval:= (101-Speed); // 101 car l'interval ne doit pas être à zero
      Timer1.Enabled:= true; 
    end;
     
    procedure TMainForm.Timer1StartTimer(Sender: TObject);
    begin
      LX := 0;
      LY := 0;
      fStep := 0;
      btnGo.Enabled := False;
    end;
     
    procedure TMainForm.Timer1StopTimer(Sender: TObject);
    begin
      btnGo.Enabled := True;
    end;
     
    procedure TMainForm.Timer1Timer(Sender: TObject);
    begin
      Inc(fStep);
      LBGRATemp.FillRect(ClientRect, BGRABlack);
      LBGRATemp.PutImage(0, 0, fBGRAFrom, dmSet, Opacity(False));
       // traitement ici...
       LY := - imgResult.ClientHeight + imgResult.ClientHeight * fStep div 100; // OVERDOWN
      LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);
      LBGRATemp.Draw(imgResult.Canvas, 0, 0);
      if fstep = 100 then Timer1.Enabled:=false;
    end;
    EDIT : Petite video de demonstration

    • "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

  9. #9
    Responsable Delphi

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    février 2013
    Messages
    1 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 1 339
    Points : 17 591
    Points
    17 591
    Billets dans le blog
    73

    Par défaut

    Bravo

    J'aurais dû m'en douter, car ce TImage est une source continuelle de problèmes. Heureusement, le composant lui-même est un descendant de TGraphicControl fonctionnant avec un TTimer, d'où la fluidité des transitions, même sous un Linux en VM. Le composant final n'a aucun besoin d'un composant TImage pour s'afficher, ce qui est une bonne nouvelle (dans un premier temps, il a même été descendant de TPaintBox, un composant beaucoup plus léger - d'ailleurs, il faudrait voir s'il ne convient pas lui aussi, le TPanel étant à mon goût trop généraliste et pas spécialement prévu pour afficher des images).

    En revanche, je ne vais pas adopter dans les exemples le TTimer (qui est bien sûr la solution choisie pour le composant), car je souhaite que le lecteur se concentre sur les transitions et non sur leur déroulement. En particulier, afin d'éviter des chevauchements et des problèmes de synchronisation (particulièrement sensibles avec Windows cette fois-ci), il faut travailler avec des états, ce que je présenterai bien plus tard... Le code que tu présentes a en effet un défaut : si tu as pensé à éviter une valeur nulle pour le déclenchement de l'événement OnTimer, il reste un problème en suspens pour les vitesses rapides : que se passe-t-il si l'intervalle du timer est très proche, voire supérieur au temps de réalisation de la transition ? Il faut penser aux rotations plutôt chronophages, par exemple. De plus, l'intervalle du TTimer est imprécis et l'expérience montre qu'en dessous de 10ms, l'utilisateur rencontre (souvent) des problèmes de synchronisation.

    Je vais cependant, grâce à toi, ajouter une note dans le tutoriel et te citer comme collaborateur.

    Ce qui m'ennuie le plus, c'est que je suis devant un cruel dilemme : simplement signaler la modification ou revoir les 4 tutoriels qui sont déjà rédigés avec leurs 40 exemples .

    Bonne journée,

    Gilles
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

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

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Citation Envoyé par gvasseur58 Voir le message
    Bravo

    J'aurais dû m'en douter, car ce TImage est une source continuelle de problèmes. Heureusement, le composant lui-même est un descendant de TGraphicControl fonctionnant avec un TTimer, d'où la fluidité des transitions, même sous un Linux en VM. Le composant final n'a aucun besoin d'un composant TImage pour s'afficher, ce qui est une bonne nouvelle (dans un premier temps, il a même été descendant de TPaintBox, un composant beaucoup plus léger - d'ailleurs, il faudrait voir s'il ne convient pas lui aussi, le TPanel étant à mon goût trop généraliste et pas spécialement prévu pour afficher des images).
    Oui c'est vrai le TPanel est généraliste mais on veux juste avoir accès au Canvas. On pourrais tout aussi bien se servir du Canvas de la fenêtre, ça ne changerai pas grand chose. D'ailleur bon nombre d'exemple réaliser par Lainz sont basés sur le Canvas de la fenêtre et le "OnPaint" pour l'affichage d'animation

    Citation Envoyé par gvasseur58 Voir le message
    En revanche, je ne vais pas adopter dans les exemples le TTimer (qui est bien sûr la solution choisie pour le composant), car je souhaite que le lecteur se concentre sur les transitions et non sur leur déroulement. En particulier, afin d'éviter des chevauchements et des problèmes de synchronisation (particulièrement sensibles avec Windows cette fois-ci), il faut travailler avec des états, ce que je présenterai bien plus tard... Le code que tu présentes a en effet un défaut : si tu as pensé à éviter une valeur nulle pour le déclenchement de l'événement OnTimer, il reste un problème en suspens pour les vitesses rapides : que se passe-t-il si l'intervalle du timer est très proche, voire supérieur au temps de réalisation de la transition ? Il faut penser aux rotations plutôt chronophages, par exemple. De plus, l'intervalle du TTimer est imprécis et l'expérience montre qu'en dessous de 10ms, l'utilisateur rencontre (souvent) des problèmes de synchronisation.
    Normal, je comprend. Sinon la solution pour la synchronisation est d'utiliser un "ThreadTimer" j'en ai un, je pourrais mettre la source à disposition

    Citation Envoyé par gvasseur58 Voir le message
    Je vais cependant, grâce à toi, ajouter une note dans le tutoriel et te citer comme collaborateur.
    Merci

    Citation Envoyé par gvasseur58 Voir le message
    Ce qui m'ennuie le plus, c'est que je suis devant un cruel dilemme : simplement signaler la modification ou revoir les 4 tutoriels qui sont déjà rédigés avec leurs 40 exemples .

    Bonne journée,

    Gilles
    Remplaces simplement le TImage par un TPaintBox cela me semble le plus simple, non ?

    Bonne fin de journée également

    Allez hop je retourne au boulot (le vrai cette fois)
    • "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

  11. #11
    Responsable Delphi

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    février 2013
    Messages
    1 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 1 339
    Points : 17 591
    Points
    17 591
    Billets dans le blog
    73

    Par défaut

    Je reviens avec d'autres expérimentations en VM. En fait, il suffit d'utiliser un TPanel (pour lequel j'ai gardé le nom imgResult), de retirer le Repaint (qui efface le canevas du composant) et d'ajouter un ProcessMessages pour récupérer les clics sur les boutons et curseurs. Pas besoin de surcharger le gestionnaire OnPaint.

    Procédure :
    1. Je remplace le TImage du résultat par un TPanel ou un TPaintBox renommé imgResult.
    2. Je supprime imgResult.Repaint ;
    3. J'ajoute Application.ProcessMessages.

    Il me reste un léger problème de scintillement . J'imagine qu'il reste une question de mémoire vidéo comme l'a suggéré Jipété, mais ça ne règle pas tout...
    Quelqu'un a t-il testé les exemples sur d'autres machines pur Linux ?

    Gilles

    [EDIT]
    Citation Envoyé par BeanzMaster Voir le message
    Remplace simplement le TImage par un TPaintBox cela me semble le plus simple, non ?
    Oui, sauf qu'il faut que je le fasse dans 40 applications .
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  12. #12
    Responsable Delphi

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    février 2013
    Messages
    1 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 1 339
    Points : 17 591
    Points
    17 591
    Billets dans le blog
    73

    Par défaut

    Le tutoriel a été mis à jour. J'ai remplacé le composant TImage par un composant TPaintBox : certaines portions de code ont donc été modifiées, mais aussi le fichier LFM et des copies d'écran. Il serait intéressant de voir pourquoi un composant aussi commun que TImage est aussi peu efficace sous Linux . Les autres épisodes de la série sont prêts : il va falloir que je vérifie que les modifications apportées n'ont pas de conséquences fâcheuses sur certaines transitions.

    Il va sans dire que Jérôme a été cité pour son apport à la fin du tutoriel
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

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

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

    Informations forums :
    Inscription : septembre 2015
    Messages : 811
    Points : 2 291
    Points
    2 291
    Billets dans le blog
    2

    Par défaut

    Citation Envoyé par gvasseur58 Voir le message
    Je reviens avec d'autres expérimentations en VM. En fait, il suffit d'utiliser un TPanel (pour lequel j'ai gardé le nom imgResult), de retirer le Repaint (qui efface le canevas du composant) et d'ajouter un ProcessMessages pour récupérer les clics sur les boutons et curseurs. Pas besoin de surcharger le gestionnaire OnPaint.

    Procédure :
    1. Je remplace le TImage du résultat par un TPanel ou un TPaintBox renommé imgResult.
    2. Je supprime imgResult.Repaint ;
    3. J'ajoute Application.ProcessMessages.

    Il me reste un léger problème de scintillement . J'imagine qu'il reste une question de mémoire vidéo comme l'a suggéré Jipété, mais ça ne règle pas tout...
    Quelqu'un a t-il testé les exemples sur d'autres machines pur Linux ?

    Gilles

    [EDIT]
    Pour le problème de scintillement essayes de rajouter Doublebuffered := true dans le OnCreate de la form.

    Citation Envoyé par gvasseur58 Voir le message
    Oui, sauf qu'il faut que je le fasse dans 40 applications .
    Tu peux utiliser notepad++ pour remplacer les occurrences dans les fichiers Pas et lfm

    Citation Envoyé par gvasseur58 Voir le message
    Le tutoriel a été mis à jour. J'ai remplacé le composant TImage par un composant TPaintBox : certaines portions de code ont donc été modifiées, mais aussi le fichier LFM et des copies d'écran. Il serait intéressant de voir pourquoi un composant aussi commun que TImage est aussi peu efficace sous Linux . Les autres épisodes de la série sont prêts : il va falloir que je vérifie que les modifications apportées n'ont pas de conséquences fâcheuses sur certaines transitions.
    Le problème du TImage est un problème entre multi-plateforme. Dans Windwos et Linux et en plus suivant le Bureau (GTK, QT...) l'affichage n'est pas gérer de la même façon. Une autre problème avec le TImage c'est qu'il contient un bitmap qui s'affiche avant le canvas. Pour pouvoir utiliser le TImage convenablement. Il faut transférer le BGRABitmap dans le Bitmap du TImage et non pas sur le Canvas. L'erreur d'affichage et la lenteur vient de la je pense. Derrière la fonction Draw de BGRABitmap se cache en réalité la fonction TCanvas.StretchDraw(); celle-ci est déja à la base moins performante sous Linux que sous Windows et c'est une fonction plutôt complexe à cause de la gestion des Widgets. Du coup il y a surement un conflit interne avec le TImage qui utilise également cette fonction pour l'affichage du bitmap sur son canvas.

    Citation Envoyé par gvasseur58 Voir le message
    Il va sans dire que Jérôme a été cité pour son apport à la fin du tutoriel
    Merci
    • "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

  14. #14
    Membre confirmé

    Profil pro
    Inscrit en
    juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2009
    Messages : 112
    Points : 524
    Points
    524

    Par défaut

    Bonjour !

    Joie de voir un tutoriel BGRABitmap.

    Effectivement, le composant TImage est une surcouche qui peut ralentir l'affichage. Le scintillement peut être empêché sur la PaintBox avec DoubleBuffer, ou bien en utilisant le composant TBGRAVirtualScreen du paquet BGRAControls. Ce composant expose un évenement OnRedrawBitmap. Il est possible de demander un réaffichage différé avec DiscardBitmap ou bien de demander un réaffichage immédiat avec RedrawBitmap. Cela dit, cela demanderait de refactoriser un peu le code qui pour le moment est une boucle qui contient le dessin.

    Notez que sous MacOS, dans mes souvenirs il n'est pas possible de redessiner directement sur la fenêtre. Donc une PaintBox est nécessaire. D'autre part, il n'est pas possible non plus de dessiner en dehors d'un événement OnPaint. Une boucle qui contient le dessin ne fonctionnerait donc pas pour cette plateforme. Une approche intermédiaire pourrait fonctionner : une boucle qui incrémente le temps et appelle RedrawBitmap/Invalidate et dans l'évenement le dessin en fonction de la position temporelle. Afin que cela marche sous Linux il peut être nécessaire d'appeler Application.ProcessMessages parce que le rafraîchissement des contrôles ne se fait parfois pas quand on fait Repaint mais quand on laisse la main à la boucle de message. Pas sûr que ce soit si simple au final.

    En fin de compte, le plus simple qui marche pour toutes les plateformes est l'utilisation d'un Timer qui appelle DiscardBitmap ou bien Invalidate avec une PaintBox et de dessiner dans l'évenement OnPaint.

    Il se peut cependant que le taux du Timer soit un peu lent. Si on veut utiliser toute la CPU disponible, on peut utiliser Application.AddOnIdleHandler / RemoveOnIdleHandler pour inscrire une procédure qui sera appelée dès que possible. Dans cette procédure on peut appeler Sleep et Invalidate, ce qui déclenchera l’événement OnPaint tout le temps.

    Au sujet de la fonction StretchDraw, si le rectangle de destination a la même taille que l'image, c'est en fait équivalent à Draw. D'ailleurs en fait, la fonction de la LCL Draw appelle la fonction StretchDraw et c'est le Widgetset en dessous qui détermine en fait s'il y a lieu d'étirer ou pas. Alors je ne pense pas que la lenteur vienne de là. J'ai un vague souvenir comme quoi le composant TImage a lui-même un Timer pour se rafraichir. L'intérêt est que l'on peut dessiner sur le Canvas d'une TImage et cela ne réaffiche pas l'image pour chaque ligne tracée.

    Cordialement,

    Johann
    Par-delà nos conceptions du bien et du mal se trouve une prairie. Je te rencontrerai là-bas.

  15. #15
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    7 219
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 7 219
    Points : 10 280
    Points
    10 280

    Par défaut

    Salut,

    ça tombe bien, tout ça, car je suis en train de me prendre la tête avec des vieux machins pour du gif, qui marchent sur 3 pattes, et vu le tuto de Gilles expliquant qu'on peut se passer d'installation pour BGRA, je me suis dit que j'allais tenter le coup.

    Bon, sous Linux la génération de la doc a lamentablement merdé, me suis retrouvé avec un dossier "\doc" et 8 fichiers "doc\blabla.txt" dont je ne sais que faire, mais là n'est pas le plus grave.

    Ayant vite repéré le dossier test/testgif, j'ai eu la joie de faire fonctionner le projet1 ootb (Out Of The Box, comme on dit) juste après la compil indiquée par Gilles.
    Content, le monsieur.
    Mais ça n'a pas duré...
    Là où ça s'est grave compliqué, c'est avec projet2.lpi : dès l'ouverture, badaboum :
    Nom : bgracontrols.png
Affichages : 76
Taille : 25,6 Ko

    J'ai supposé qu'il s'agissait de bglcontrols.lpk, à qui j'ai fait subir le même traitement que pour l'autre lpk (ouverture, compil) et j'ai pu aller un peu plus loin :
    Nom : virtualscreen.png
Affichages : 80
Taille : 33,3 Ko

    Mais pour passer cette étape il m'a fallu bidouiller le .pas du projet :
    uses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
    //  BGRABitmap, BGRABitmapTypes, BGRAAnimatedGif, BGRAVirtualScreen, BCTypes;
      BGRABitmap, BGRABitmapTypes, BGRAAnimatedGif, BGLVirtualScreen;//, BCTypes;
     
    type
     
      { TForm2 }
     
      TForm2 = class(TForm)
        BGRAVirtualScreen1: TBGLVirtualScreen;//TBGRAVirtualScreen;
    On notera BCTypes en commentaires, ne lui ayant pas trouvé de correspondance.

    Le drame vient ensuite :
    Citation Envoyé par circular17 Voir le message
    ou bien en utilisant le composant TBGRAVirtualScreen du paquet BGRAControls. Ce composant expose un évenement OnRedrawBitmap. Il est possible de demander un réaffichage différé avec DiscardBitmap ou bien de demander un réaffichage immédiat avec RedrawBitmap.

    Comme dit précédemment, BGRAControls.lpk n'existe pas, et je pensais m'en sortir avec BGLControls, sauf que :

    Nom : discard2.png
Affichages : 75
Taille : 28,3 Ko

    et face à ça je ne sais pas quoi faire...

    De plus, si je mets les deux lignes de la procédure Timer1Timer en commentaires, c'est dead de chez dead :
    Nom : erreur_de_compil.png
Affichages : 75
Taille : 35,2 Ko


    Enfin, message pour Gilles : c'est pas au point cette histoire de ne pas installer les compos, voilà ce que je gagne quand je fais F12 pour voir la fiche :
    Nom : install_obligatoire.png
Affichages : 75
Taille : 31,3 Ko

    Debian 9.1 / Laz 1.8.2
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  16. #16
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 3 276
    Points : 11 920
    Points
    11 920
    Billets dans le blog
    5

    Par défaut

    @Jipété

    Pas tout compris à ton message.

    Je te confirme que le paquet bgracontrols.lpk existe. Où l'as-tu cherché ? Il ne fait pas partie de la bibliothèque BGRABitmap, mais de l'ensemble de composants BGRAControls, qui sont deux choses différentes.

    Après il est possible que certains exemples inclus dans BGRABitmap utilisent (sans peut-être suffisamment en avertir l'utilisateur) les composants BGRAControls. Quoiqu'il en soit, le composant BGRAVirtualScreen fait partie du paquet BGRAControls, et non pas de la bibliothèque BGRABitmap.

    Citation Envoyé par circular17 Voir le message
    ou bien en utilisant le composant TBGRAVirtualScreen du paquet BGRAControls.

  17. #17
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    7 219
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 7 219
    Points : 10 280
    Points
    10 280

    Par défaut

    Citation Envoyé par Roland Chastain Voir le message
    Je te confirme que le paquet bgracontrols.lpk existe. Où l'as-tu cherché ? Il ne fait pas partie de la bibliothèque BGRABitmap, mais de l'ensemble de composants BGRAControls, qui sont deux choses différentes.
    Ah !
    Alors c'est le tuto de Gilles qui m'a induit en erreur (oui, on joue sur les mots, Gilles propose BGRAbitmap et ne dit pas un mot de ces fichus contrôles), et la page de téléchargement de BGRABitmap qui est mal fichue car nulle part il n'est question de cette subtilité.

    Et d'abord, pourquoi faut-il qu'il y ait plusieurs .lpk différents ?
    À quand un seul paquet BGRAtools.lpk incluant tout, histoire que l'utilisateur ne se prenne pas la tête avec des machins de bas niveau qui lui claquent entre les mains ?

    Quand même dingue que project1.lpi fonctionne alors que dans le même dossier (test/testgif) project2.lpi balance des erreurs.

    Merci pour cette précision, Roland,

    Et pour l'affaire du doc, je propose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //        CreateDirUTF8(path+'\doc');
    //        outname := 'doc\'+docName+'.txt';
            CreateDirUTF8(path+DirectorySeparator+'doc');
            outname := 'doc'+DirectorySeparator+docName+'.txt';
    dans function MakeDocFor(AFilename: string): string;.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  18. #18
    Membre confirmé

    Profil pro
    Inscrit en
    juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2009
    Messages : 112
    Points : 524
    Points
    524

    Par défaut

    Je note la correction à apporter makedoc pour la compatibilité avec Linux.

    Ce programme n'est pas destiné aux utilisateurs. Il sert à générer la documentation sur le wiki de BGRABitmap.
    Par-delà nos conceptions du bien et du mal se trouve une prairie. Je te rencontrerai là-bas.

  19. #19
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    7 219
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 7 219
    Points : 10 280
    Points
    10 280

    Par défaut

    Citation Envoyé par circular17 Voir le message
    makedoc

    Ce programme n'est pas destiné aux utilisateurs. Il sert à générer la documentation sur le wiki de BGRABitmap.
    Rien ne l'indique nulle part. Pourquoi est-il donc dans l'archive sans aucune indication ? J'étais persuadé que c'était quelque chose qui allait générer de la doc, vu que je n'en ai pas trouvée...
    Au contraire, voilà ce qu'on trouve dans le readme.txt :
    Citation Envoyé par readme.txt
    makedoc: contains a program to make documentation from source code
    Enfin bon, je vire le dossier et je continue mes recherches.

    Quant au project2.lpi et à ses cafouillages, toujours issu du readme.txt,
    Citation Envoyé par readme.txt
    test: contains a series of test programs and examples on how to use BGRABitmap library
    et pas un mot concernant l'obligation d'installer d'autres packages...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  20. #20
    Membre confirmé

    Profil pro
    Inscrit en
    juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2009
    Messages : 112
    Points : 524
    Points
    524

    Par défaut

    Toute contribution de documentation est la bienvenue.
    Par-delà nos conceptions du bien et du mal se trouve une prairie. Je te rencontrerai là-bas.

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/12/2013, 14h29
  2. [Images] Créer des miniatures d'une image
    Par jeangaza dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 15/06/2010, 15h42
  3. Créer des Section dans un Image JPG
    Par Charo dans le forum Imagerie
    Réponses: 2
    Dernier message: 31/01/2007, 09h56

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