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

Lazarus Pascal Discussion :

Faire tourner une image


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 2
    Par défaut Faire tourner une image
    Bonjour,

    Je cherche à faire un algorithme qui me fait tourner une image d'un certain angle. J'ai réussi à écrire un truc qui marche en calculant la nouvelle position de chaque pixel après rotation et à placer chaque pixel à sa nouvelle position dans une nouvelle image temporaire.

    Le problème, c'est que même sur une image pas très très grosse, ça fait pas mal de calcul et du coup si je dessine l'image toute les x secondes avec un TTimer, ça rame pas mal dès que je demande une cadence suffisamment élevée pour que la rotation apparaisse fluide.

    Voilà mon code :

    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
    procedure TForm2.Timer1Timer(Sender: TObject);
    var i,j,x,y:integer;
    begin
         Form2.Canvas.brush.color := clwhite;
         imagetemp := TBitmap.create;
         imagetemp.width:=500;
         imagetemp.height:=500;
         for i := 0 to imagetemp.Width do
         begin
               for j:= 0 to imagetemp.height do
               begin
                   x := 128+round((i-200)*cos(Pi*angle/180)-(j-200)*sin(Pi*angle/180));
                   y := 99+round((i-200)*sin(Pi*angle/180)+(j-200)*cos(Pi*angle/180));
                   imagetemp.Canvas.Pixels[i+50,j+50]:=image.Canvas.Pixels[x,y];
                end;
         end;
         Form2.canvas.Draw(0,0,imagetemp);
         imagetemp.free;
         angle:=angle+5;
    end;
    (Les "128","200", etc. servent juste à bidouiller pour que ça tourne bien autour du centre de l'image.)

    Je sais qu'on peut utiliser des librairies pour faire ce genre de trucs, mais je voulais savoir si c'était pas possible d'améliorer mon truc pour que ça fonctionne ?

    Merci.

  2. #2
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Par défaut
    La valeur de ton angle ne change durant toute la rotation donc la 1ere chose que tu peux faire c'est pré-calculer tes sinus et cosinus en début de procédure, stocker les résultats dans des variables et utiliser ces variables dans la boucle.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 940
    Billets dans le blog
    6
    Par défaut
    Il est peut-être également possible de calculer quelques images à l'avance dans un thread de manière à avoir un simple affichage dans le OnTimer ?

    Si les images ont toutes la même taille, un TImageList pour les stocker, un index pour savoir où on en est, et un Synchronise dans le thread pour ajouter les images ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 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 !

  4. #4
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 2
    Par défaut
    j'ai modifié mon programme pour qu'il recalcule pas le sinus et cosinus à chaque fois pour le même angle et pour qu'il enregistre les images tournées dans un TStringList, et qu'il affiche à partir de ça.

    Du coup ça marche impec mais le seul problème c'est que je suis obligé d'attendre qu'il ai fini de calculer toutes les images avant d'afficher, sinon si j'essaye d'afficher en même temps il va afficher plus vite que le calcul et j'ai des erreurs de violation de mémoire du coup.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 940
    Billets dans le blog
    6
    Par défaut
    D'où l'utilité d'un thread qui s'exécute en parallèle de l'appli, calcule une seule image à la fois, et quand elle est prête utilise un Synchronize pour l'ajouter à un TImageList (ou l'enregistre et met son chemin dans un TStringList).

    Le OnTimer accèdera à la liste (donc pas d'interférence, car synchronisée si le thread y accède) et cherchera la nième image (compteur) pour l'afficher.

    Si le calcul d'une image prend plus de temps que l'intervalle du Timer, ce n'est simplement pas possible... on peut tricher un peu en réglant un petit délai supplémentaire pour attendre l'image, si compteur=List.Count, évitant ainsi les violations d'accès. A voir ensuite si rattrapage du délai initial.

    Sinon, tu as 72 images à calculer, dont 18 rotations et 3 symétries (90°, 180° et 270°) pour chaque. En Delphi, avec les Scanlines, il est sûrement plus rapide de calculer les symétries que de refaire le calcul trigo. Sous Lazarus, il faut "ruser" pour retrouver un équivalent des ScanLines, cf. posts sur ce sujet
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 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 !

Discussions similaires

  1. [Débutant] Faire tourner une image selon un axe calculé
    Par Attila54 dans le forum VB.NET
    Réponses: 3
    Dernier message: 29/11/2011, 15h59
  2. Comment faire tourner une image GIF ?
    Par Claude_Azoulai dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 28/07/2009, 10h21
  3. Faire tourner une image en fonction des jours
    Par bastien_hj dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 04/04/2009, 17h25
  4. faire tourner une image
    Par paulselvan dans le forum Macros et VBA Excel
    Réponses: 20
    Dernier message: 10/08/2008, 16h22
  5. Réponses: 7
    Dernier message: 28/06/2007, 08h26

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