IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

 Delphi Discussion :

Affichage "sympa" de cartes à jouer


Sujet :

Delphi

  1. #21
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,


    Paul TOTH : ... voici la technique que j'évoquais plus haut, j'utilise GDI+ mais la même chose pourrait être faite en GDI, Graphics32, OpenGL...
    C'est absolument chouette et la fluidité de réaction au déplacement de la souris est remarquable.
    Le seul problème est qu'il faut maîtriser les subtilités de GDI+ pour arriver à ce résultat en seulement une centaine de lignes.

    cochez la checkbox pour voir le bitmap de détection des pixels
    ... pas trouvé de checkbox dans la version présente dans le zip ... mais ça c'est du détail ...

    Je suis sûr que Coussati va adorer.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #22
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,



    C'est absolument chouette et la fluidité de réaction au déplacement de la souris est remarquable.
    Le seul problème est qu'il faut maîtriser les subtilités de GDI+ pour arriver à ce résultat en seulement une centaine de lignes.


    ... pas trouvé de checkbox dans la version présente dans le zip ... mais ça c'est du détail ...

    Je suis sûr que Coussati va adorer.

    A+.
    J'ai du oublier de sauvegarder avant de faire mon ZIP

    mais je me suis amusé à reprendre le code de RotateBitmap pour faire un version pure GDI

    à la différence de RotateBitmap qui calcule le rectangle de l'image une fois la rotation effectuée et recherche pour chaque pixel s'il correspond à un pixel du bitmap source, j'applique une rotation à chaque pixel du bitmap pour le dessiner...mais comme ça fait des trous, je double chaque ligne et chaque colonne, donc un pixel source est dessiné 4 fois...je ne suis pas certain que ce soit plus rapide mais ça permet d'avoir un temps identique pour dessiner l'image dans n'importe quelle position et d'ignorer automatiquement tous les pixels transparents (qui certes, ne sont pas bien nombreux ici)

    à noter aussi que dans cette version je n'utilise qu'un seul bitmap, en fait un tableau d'entier comme décrit dans mon article, et c'est le canal Alpha qui identifie directement la carte concernée.

    Cartes.zip


    Nom : Capture-2.jpg
Affichages : 620
Taille : 149,8 Ko
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #23
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Je suis sûr que Coussati va adorer.
    je ne te le fais pas dire !

    salut à tous

    que de belles choses à mon retour de week end, alors avant tout je vous adresse un big merci pour vos exemples

    Paul a réussit l'idéal, exactement ce qu'il me fallait

    par contre, je n'avais jamais utilisé GDI, il y a pas mal de nouvelles choses que je ne connais pas

    il va me falloir un peu de temps avant de maitriser tout ça, mais je vais travailler tout ça ^^

    à chaud, quelques précisions : il me semble que tu dessines un bitmap à l'ouverture de la fenêtre ? si j'ai des Timages en fond (background du programme) ça ne posera pas de problème ? et lorsqu'une carte a été joué par exemple, comment la retirer efficacement ? tout effacer et recréer les cartes une à une (en excluant celle qui a été joué bien sur) ?

    merci encore

  4. #24
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Paul TOTH : J'ai du oublier de sauvegarder avant de faire mon ZIP
    Ok, vu et testé la version avec la checkbox : je la conserve pour m'en inspirer le cas échéant car j'ai un peu utilisé le GDI+ de chez Mitov.

    à noter aussi que dans cette version je n'utilise qu'un seul bitmap, en fait un tableau d'entier comme décrit dans mon article, et c'est le canal Alpha qui identifie directement la carte concernée.
    Bin oui, et j'aimerais bien pouvoir transformer la fonction ci-après de sorte qu'elle me renvoie un TRGBQuad à la place du TColor : ( une idée ??? )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function ScreenPixelMousePos(var xm, ym: integer): TColor;
    // Result : renvoie la couleur du point de l'écran sous la souris même hors fiche
    // var xm,ym : renvoient la position de la souris
    var Dc: HDC;
    begin
      DC := CreateDC('DISPLAY', nil, nil, nil);
      try
        xm := Mouse.CursorPos.X; ym := Mouse.CursorPos.Y;
        Result := GetPixel(DC, xm, ym);
      finally
        DeleteDc(DC);
      end;
    end;
    ... car avec ma solution actuelle je suis obligé de modifier légèrement les couleurs des cartes d'un Delta pour pouvoir en déduire le numéro de la carte, alors qu'en planquant ce numéro dans le rgbReserved on conserve toutes les couleurs d'origine.

    ... je me suis amusé à reprendre le code de RotateBitmap pour faire un version pure GDI
    En tous cas la version GDI réagit un peu plus rapidement que le TRotateBitmap.

    Coussati : je ne te le fais pas dire !
    Je suis sûr que tu as, comme moi, aussi été séduit par la PinUp des cartes de Paul TOTH
    J'en ai donc déduit que pour l'Affichage "sympa" de cartes à jouer la règle n°1 est d'utiliser des cartes "sympa".
    Donc j'ai remplacé mes petites cartes riquiqui par des cartes deux fois plus grandes, mais je n'en ai pas trouvé d'aussi chouettes que la PinUp.

    Comme j'ai enfin réussi à améliorer le déplacement et la rotation d'une carte par ripage avec la souris, voici un nouveau ZIP
    ... mais le déplacement est un peu saccadé, comme si le code de RotateBitmap re-calculait tout lors d'un simple déplacement dx,dy.

    A+.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  5. #25
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Coussati Voir le message
    à chaud, quelques précisions : il me semble que tu dessines un bitmap à l'ouverture de la fenêtre ? si j'ai des Timages en fond (background du programme) ça ne posera pas de problème ? et lorsqu'une carte a été joué par exemple, comment la retirer efficacement ? tout effacer et recréer les cartes une à une (en excluant celle qui a été joué bien sur) ?
    en GDI+ tu peux tranquillement mettre une image de fond puisquie c'est FPixels qui détermine la carte

    en GDI (pas +) il faut soit remplir FBitmap avec l'image en mettant 0 dans le canal alpha, soit utiliser 2 bitmaps comme en GDI+

    quand à tout redessiner pour supprimer une carte la réponse est oui, d'ailleurs c'est ce que fait la VCL quand tu supprimes un TImage

    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,
    Bin oui, et j'aimerais bien pouvoir transformer la fonction ci-après de sorte qu'elle me renvoie un TRGBQuad à la place du TColor : ( une idée ??? )
    je ne pense pas que GDI conserve la valeur du canal alpha...à vérifier. Moi j'utilise un array of Integer que je peux manipuler comme je veux.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #26
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,


    Paul TOTH: je ne pense pas que GDI conserve la valeur du canal alpha...à vérifier. Moi j'utilise un array of Integer que je peux manipuler comme je veux.
    Je me suis rendu compte que le GDI ne conserve pas le canal alpha,
    Du coup je m'en suis sorti en traçant les silhouettes des cartes inclinées en nuances de bleu dans un BitMap et c'est la valeur du bleu qui me donne le numéro de la carte sous la souris s'il s'y trouve une.

    Et voici le résultat : (j'ai piqué ta Queen PinUp)
    Le numéro de la carte sous la souris s'affiche sur un TLabel accroché au curseur de la souris.

    - Pour re-complier le code, installer d'abord le composant RotateImage présent dans le ZIP,
    - Sinon on peut tester le résultat avec l'EXE présent dans le ZIP.

    A+.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  7. #27
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Petites questions à Paul TOTH concernant l'utilisation de sa procedure TForm1.RotateBitmap(var ABitmap: TBitmap; x, y, Angle, rx, ry: Integer; AndMask, OrMask: Cardinal);
    précédée par :
    {
    Dessine un bitmap en x, y avec rotation de centre rx, ry
    AndMask et OrMask permettent de modifier la couleur de chaque pixel
    }
    1) Je suis en-train d'analyser le code mais d'entrée de jeu je tombe sur un truc que je ne pige pas :
    Comment fait-on pour positionner le BitMap à incliner en fixant à la fois la position x,y (de son angle Top-Left, je suppose), celle d'un centre de rotation de coordonnées ry,ry et l'angle de rotation
    car dès qu'on a fixé la position x,y d'un de ses angles ainsi que l'angle de rotation le seul degré de liberté pour la rotation c'est de tourner autour du centre x,y ???
    ... mais puisque l'utilisation de cette procédure fonctionne avec le jeu de cartes, je suppose qu'il doit y avoir une explication logique.
    ... pour faciliter les explications je joins ici un petit croquis : Pour fixer la valeur des paramètres x, y et rx, ry est-ce le cas A qu'il faut prendre en considération ou le cas B, ou un autre ???

    2) Puis les choses se compliquent encore davantage dans la FormPaint() où la RotateBitmap() est appelée avec des paramètres négatifs pour le centre de rotation rx,ry :
    RotateBitmap(FQueen, ClientWidth div 2, ClientHeight div 2 + FQueen.Height, 10 * Index, -FQueen.Width, -3 * FQueen.Height, AndMask, OrMask);
    ce qui suppose un centre de rotation situé au Nord des cartes alors que les cartes en éventail convergent vers un centre situé au Sud de l'écran.
    ... et là je suis complètement largué: ... on les fixe comment ce centre rx,ry et la position x,y si on veut positionner un BitMap incliné en un endroit précis d'une fiche ???

    A+.
    Images attachées Images attachées  
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #28
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    ahah, le bon dessin c'est le cas B

    x et y c'est le point F
    rx et ry c'est la translation qui fait que l'origine du bitmap n'est pas en haut à gauche de l'image mais justement en F donc le point (0,0) devient (-FQueen.Width, -3*FQueen.Height)

    pourquoi deux points ? tout simplement car si tu avances de 2 pas, que tu tournes à 45° puis tu fais 3 pas, tu n'arrives pas au même endroit que si tu fais l'inverses ou que si tu fais 3+2 = 5 pas avant de tourner.

    donc en trois étapes on a:
    1) translation rx, ry pour déplacer l'origine de l'image (-FQueen.Width, -3*FQueen.Height)
    2) rotation de l'image suivant le point F
    3) translation de F en x, y pour positionner l'image (ClientWidth/2, ClientHeight/2+ FQueen.Height)
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #29
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Paul TOTH :
    ahah, le bon dessin c'est le cas B
    x et y c'est le point F
    rx et ry c'est la translation qui fait que l'origine du bitmap n'est pas en haut à gauche de l'image mais justement en F donc le point (0,0) devient (-FQueen.Width, -3*FQueen.Height)
    pourquoi deux points ? tout simplement car si tu avances de 2 pas, que tu tournes à 45° puis tu fais 3 pas, tu n'arrives pas au même endroit que si tu fais l'inverses ou que si tu fais 3+2 = 5 pas avant de tourner.
    OK, mille fois merci, je commence à y voir plus clair, mais c'était un peu tordu à comprendre en l'absence d'un dessin. Et OK pour les autres explications.

    Je pose ces questions car je suis en-train de fignoler une autre variante sans utilisation de GDI+ mais simplement du pf32bit avec TRGBQuad et la Color: Cardinal qui est combinée avec AndMask et OrMask: Cardinal me pose un petit
    problème : comment convertit-on un Cardinal combiné avec AndMask et OrMask en TRGBQuad ???

    Par contre pour combler les trous je n'utilise pas les deux boucles imbriquées for dy := 0 to 1 do ... for dy := 0 to 1 do
    mais plus simplement j'affecte la Color du pixel-source simultanément au pixel-destination et aux pixels situés au Nord et à l'Ouest du pixel-destination qui à son tour sera recouvert par un suivant lorsqu'il se trouvera à son Nord : même à la loupe il est difficile de déceler une différence de qualité ... et on évite les boucles imbriquées.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  10. #30
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-salut,

    Bin, finalement j'ai trouvé : au lieu de chercher à convertir, j'ai tout simplement remplacé mes pRGBQuad en pCardinal et le AndMask et OrMask fonctionne.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  11. #31
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Re-salut,

    Bin, finalement j'ai trouvé : au lieu de chercher à convertir, j'ai tout simplement remplacé mes pRGBQuad en pCardinal et le AndMask et OrMask fonctionne.

    A+.
    oui sinon pRGBQuad et pCardinal sont tous les deux des pointeurs vers 4 octets, ils sont donc compatibles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var
      i: Integer;
      c: PCardinal;
      q: pRGBQuad;
    begin
      c := @i;
      q := pRGBQuad(c);
      pRGBQuad(c).peRed := 5;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #32
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Paul TOTH : oui sinon pRGBQuad et pCardinal sont tous les deux des pointeurs vers 4 octets, ils sont donc compatibles
    OK, merci beaucoup, c'est rassurant, cela permettra certaines gymnastiques en cas de besoin.

    Pour ce qui est de la migration de l'application depuis ta version GDI+ vers du pur Delphi et sans TRotateImage je n'affiche pour l'instant le résultat de la rotation que dans un TImage et la qualité du rendu peut être constaté dans le *jpg ci-joint.

    L'étape suivante sera de modifier en particulier la procedure TForm1.FormPaint() et la procedure TForm1.FormMouseMove() pour l'adapter à mon cas de non-utilisation de GDI+ et à ce sujet j'ai quelques petites questions :
    1) Est-ce que je peux supprimer toutes ces directives vu que je n'utilise pas GDI+ ??? :

    {$R 'resource.res' 'resource.rc'}

    {-$DEFINE GDIP}

    {$IFDEF GDIP} : présent 7 fois
    {$ELSE}
    {$ENDIF}

    2) Si NON, à quoi servent-elles ??? En particulier celles dans TForm1.FormPaint() et dans TForm1.FormMouseMove.

    A+.
    Images attachées Images attachées  
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #33
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,


    OK, merci beaucoup, c'est rassurant, cela permettra certaines gymnastiques en cas de besoin.

    Pour ce qui est de la migration de l'application depuis ta version GDI+ vers du pur Delphi et sans TRotateImage je n'affiche pour l'instant le résultat de la rotation que dans un TImage et la qualité du rendu peut être constaté dans le *jpg ci-joint.

    L'étape suivante sera de modifier en particulier la procedure TForm1.FormPaint() et la procedure TForm1.FormMouseMove() pour l'adapter à mon cas de non-utilisation de GDI+ et à ce sujet j'ai quelques petites questions :
    1) Est-ce que je peux supprimer toutes ces directives vu que je n'utilise pas GDI+ ??? :

    {$R 'resource.res' 'resource.rc'}

    {-$DEFINE GDIP}

    {$IFDEF GDIP} : présent 7 fois
    {$ELSE}
    {$ENDIF}

    2) Si NON, à quoi servent-elles ??? En particulier celles dans TForm1.FormPaint() et dans TForm1.FormMouseMove.

    A+.
    alors la directive $R permet d'inclure le BITMAP en ressource, en GDI+ je charger un PNG depuis le disque (GDI+ ne sait pas lire depuis une ressource, il faut lui fournir un IStream et c'était pénible à faire ...)

    pour ce qui est des $IFDEF/$ELSE/$ENDIF c'est de la compilation conditionnelle, en fait le projet est soit un GDI soit en GDI+ selon que tu définies ou pas GDIP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    {$DEFINE GDIP} // GDIP est défini
     
    {$IFDEF GDIP} // oui
      // code compilé
    {$ELSE} // sinon
      // code IGNORE par le compilateur !!!
    {$ENDIF}

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    {-$DEFINE GDIP} // ça c'est juste un commentaire clasique, donc GDIP n'est pas défini !
     
    {$IFDEF GDIP} // ben non du coup
      // code ignoré !
    {$ELSE} // sinon
      // code compilé !!!
    {$ENDIF}
    donc si tu veux supprimer ce qui concerne GDIP tu peux supprimer tout le code entre {$IFDEF GDIP} et {$ELSE}...attention il y a du code placé en {$IFNDEF GDIP} et {$ENDIF} là c'est du code compilé quand GDIP n'est pas défini.

    par ailleurs je constate dans ton image que tu ne gères pas la transparence, les coins de la carte sont dessinés.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  14. #34
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Paul TOTH : alors la directive $R permet ... pour ce qui est des $IFDEF/$ELSE/$ENDIF c'est de la compilation conditionnelle
    OK, merci beaucoup pour ces infos.
    Entre-temps je les ai toutes virées et pu continuer sans problème.

    par ailleurs je constate dans ton image que tu ne gères pas la transparence, les coins de la carte sont dessinés.
    Ce problème est maintenant réglé : voir la nouvelle capture d'écran ci-jointe.
    Finalement j'ai simplifié à l'extrême :
    - j'ai supprimé les AndMask et OrMask et j'affiche le n° de carte sur un TLabel accroché au crHandPoint, (en jaune sur la capture d'écran, le crHandPoint disparaît lors de la capture),
    - pour le FBitmap (array of Cardinal) je lui fais couvrir toute la zone survolable par la souris ( SetLength(FBitmap, ClientWidth * clientHeight) ),
    - j'ai quand-même ajouté la réactualisation du FBitmap en cas de ReSize, mais j'aurais pu me contenter d'un BorderStyle:=bsDialog.
    - pour une simple démo, je ne charge que deux BitMaps-Source depuis le disque et je trace leur version inclinée sur le Canvas en deux positions fixées dans le FormCreate : donc pas de calcul pour ça.
    - je n'ai pas utilisé l'astuce qui augmente la précision du sinus et du cosinus car avec des pixels 0,3x0,3 mm, dont on ne peut pas viser le centre, je crois que la précision des Extended est suffisante, et donc je me contente de boucher les trous laissés ci et là par la rotation.

    A+.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  15. #35
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    bon alors y'a pas mal de petites choses pas terrible dans ce source... désolé
    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
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      SetLength(FBitmap, ClientWidth * clientHeight);
      BorderStyle := bsSizeable;
     
      Index := 0;
      BMPSources[Index] := tBitMap.Create;
    //  BMPSources[Index].PixelFormat := pf32bit;   <- ne sert à rien le LoadFromFile écrasera cette valeur
      BMPSources[Index].LoadFromFile(ExtractFilePath(Application.ExeName) + 'HK.bmp');
     
      Angles[Index] := -30;
    //  FPixelsI[Index] := TBitmap.Create; <-- fuite de mémoire, RotaBMP remplace ce bitmap !
    //  FPixelsI[Index].Assign(BMPSources[Index]); <-- intuile
      Positions[Index].X := 100; Positions[Index].Y := 64;
    //  FPixelsI[Index] := RotaBMP(FPixelsI[Index], Positions[Index], Index, Angles[Index], FALSE);   <-- du coup on utilise BMPSource
      FPixelsI[Index] := RotaBMP(BMPSources[Index], Positions[Index], Index, Angles[Index], FALSE);
     
      inc(Index);
      BMPSources[Index] := tBitMap.Create;
    //  BMPSources[Index].PixelFormat := pf32bit;
      BMPSources[Index].LoadFromFile(ExtractFilePath(Application.ExeName) + 'HQ.bmp');
     
     
      Angles[Index] := 30;
    //  FPixelsI[Index] := TBitmap.Create;
    //  FPixelsI[Index].Assign(BMPSources[Index]);
      Positions[Index].X := 400; Positions[Index].Y := 64;
      FPixelsI[Index] := RotaBMP(BMPSources[Index], Positions[Index], Index, Angles[Index], FALSE);
     
    end;
     
    ...
     
     try
        with Result do begin
          TransparentColor := TransColor; // ouch !!! clCardinalToColor(PCardinal(BMP.ScanLine[0]));
          TransparentMode := Bmp.TransparentMode;
    je te propose une version GDI épurée Cartes-GDI.zip
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  16. #36
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    salut

    je suis toujours dans le coin, je suis vos interventions discrètement, et j'en profite pour remercier tout le monde, en particulier Gilbert et Paul qui m'ont permit de réaliser ce que je cherchait

    quelque chose que je recherche depuis presque 4 ans ! comme quoi il ne faut jamais abdiquer :p

    je clique sur résolu ?

  17. #37
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Paul TOTH : bon alors y'a pas mal de petites choses pas terrible dans ce source
    Merci beaucoup pour les corrections.

    ... désolé
    Pourquoi désolé ? C'est vachement instructif les corrections...
    j'ai surtout aimé le coup du TransparentColor := TransColor; // ouch !!! clCardinalToColor(PCardinal(BMP.ScanLine[0]));
    car avec la foison des types (TColor, Cardinal, PCardinal, PRGBQuad, et j'en passe) on se mélange vite les pinceaux.

    je te propose une version GDI épurée
    Vu : elle fait 30% de lignes en moins que la version précédente qui était truffée de directives de compilation.
    Et j'y ai beaucoup apprécié la possibilité d'afficher directement le FBitmap : array of Cardinal sur le canvas avec :
    SetDIBitsToDevice(Canvas.Handle, 0, 0, FWidth, FHeight, 0, 0, 0, FHeight, @FBitmap[0], FInfo, 0) : à retenir.
    J'ai aussi constaté que le code fonctionne aussi en virant dans le program Cartes les lignes qui concernent GDIPlus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    program Cartes;
     
    uses
      Forms,
      Main in 'Main.pas' {Form1};
     
     { GDIPAPI in 'GDIPlus\GDIPAPI.pas', < devenu superflu
      GDIPOBJ in 'GDIPlus\GDIPOBJ.pas',  < devenu superflu
      GDIPUTIL in 'GDIPlus\GDIPUTIL.pas';  < devenu superflu }
    Par contre je me demande quelle est la meilleure et la plus simple façon de boucher les trous que la rotation laisse derrière elle ???

    Coussati : je clique sur résolu ?
    A toi de voir ... de toutes façons il y a parfois des discussions qui se poursuivent même marquées du "résolu"...

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  18. #38
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    pour le SetDIBitToDevice j'ai fait un article complet dessus
    http://lookinside.free.fr/delphi.php...ler+des+pixels

    pour les trous, j'ai fait le test d'inverser la méthode et cela semble en effet plus rapide

    RotateBitmap2 dans ce code utilise l'approche utilisée dans TRotateBitmap, à savoir, on dessine le rectangle englobant le bitmap après rotation, pour chaque pixel on inverse la rotation pour retrouver le pixel du bitmap (alors que dans mon code je fais pivoter chaque pixel du bitmap pour le placer à l'écran...ce qui provoque des trous).

    Cartes-GDI-Fast.zip
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  19. #39
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Paul TOTH : pour le SetDIBitToDevice j'ai fait un article complet dessus
    Vu, intéressant.

    pour les trous, j'ai fait le test d'inverser la méthode et cela semble en effet plus rapide
    J'ai aussi constaté que je peux simplifier ma manière de boucher les trous en ne bouchant que le pixel situé à l'Ouest du pixel-destination.

    RotateBitmap2 dans ce code utilise l'approche utilisée dans TRotateBitmap, à savoir, on dessine le rectangle englobant le bitmap après rotation, pour chaque pixel on inverse la rotation pour retrouver le pixel du bitmap (alors que dans mon code je fais pivoter chaque pixel du bitmap pour le placer à l'écran...ce qui provoque des trous).
    Eh, bin voilà, effectivement qu'avec une transformée inverse on trouve toujours dans le BitMap-Source un point de couleur qu'on peut affecter à un pixel-destination qui-sinon aurait laissé un trou, c'est ça la meilleure solution.

    Sinon, si on laisse des trous, ça donne le résultat de l'image ci-jointe : le résultat n'est pas mal non plus vu que les trous forment des motifs réguliers en forme de dentelle.

    A+.
    Images attachées Images attachées  
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  20. #40
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    note que tu peux aussi réduire la taille d'affichage de l'image
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                px := x + SmallInt(((2 * (Col + rx) ) * iCos - ySin) shr 16) div 3; // point final à l'écran
                py := y + SmallInt(((2 * (Col + rx) ) * iSin + yCos) shr 16) div 3;
    en prenant un rapport de 2/3 de l'image on évite les trous mais l'image est plus petite évidemment ... sauf à agrandir l'image source
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 4 PremièrePremière 1234 DernièreDernière

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