Distortion d’images

Bonjour à tous,

Vous qui avez déjà gouté un peu à GD, vous en êtes certainement sorti de là en ayant le tournis tant les possibilités sont grandes. Je m’en viens donc nourrir à nouveau votre esprit pour d’autres élucubrations…

Entrons donc dans le vif du sujet.


Prenez une image et essayer de l’imaginer appliquée comme texture à une forme (une pièce ou un cube).
Vous pouvez arriver relativement facilement à un résultat comme celui de mon cube.

Vous le remarquerez vite, il suffit de décaler chaque ligne verticale de l’image pour transformer notre rectangle en parallélogramme. Pour l’image du « dessus », on fait cette opération 2 fois pour la placer correctement au même endroit.

Oui mais…

En bon mathématicien que je suis, cette perspective parallèle ne me plait entièrement. Dès lors, je me suis lancé dans une vue de ce même cube mais avec une perspective à points de fuite.
En jouant sur les hauteurs progressives de lignes, on arrive à un effet trapézoïdal des images qui convient pour les faces latérales mais pas pour la face supérieure. On le voit parfaitement sur le second exemple disponible sur mon Cube2.

Voilà où je m’étais arrêté il y a un petit temps déjà… Un peu perplexe déçu du résultat mais pas prêt à m’avouer vaincu. Après avoir identifié le problème, il me fallait encore envisager une solution et surtout: sa mise en pratique.

C’est là qu’interviennent les mathématiques…
Lorsqu’on imagine une image en perspective, on se rend compte que le haut (par exemple) sera plus petit que le bas. Ainsi, lorsqu’on parcourra le haut, le point sur la bas correspondant avancera plus vite, certes, mais surtout de manière proportionnelle.

Il suffit donc de copier non pas les lignes verticales mais toutes les lignes joignant un pixel du haut à son correspond en bas. Le problème c’est donc encore de copier une ligne verticale au départ généralement, sur un segment quelconque de mon image de destination.
J’ai choisis pour cela de passer en revue chaque pixel du segment.

Il reste juste à faire attention à certaines choses comme la nécessité de prendre autant de segments à copier que la longueur maximale entre les bords supérieur et inférieur.

Et puisqu’un article PHP/GD n’est pas complet sans image, voici un résultat obtenu rapidement:

Exemple de distortion d'images

Et ce qui vous intéresse: le code!

  1. span class= »st0″>’../image.class.php’;
  2.  
  3.     /* Copie un pixel d’une image à une autre */‘x’], $topxl[‘y’], $frompxl[‘x’], $frompxl[‘y’], 1, 1);
  4.     }
  5.  
  6.     /* Copie un segment d’une image sur une autre */‘x1’]$frompxls[‘x2’];
  7.         $fromdy = $frompxls[‘y1’]$frompxls[‘y2’];
  8.         $todx   = $topxls[‘x1’]$topxls[‘x2’];
  9.         $tody   = $topxls[‘y1’]$topxls[‘y2’‘x’ => $frompxls[‘x1’]+$pct*$fromdx, ‘y’ => $frompxls[‘y1’‘x’ => $topxls[‘x1’]+$pct*$todx, ‘y’ => $topxls[‘y1’]+$pct*$tody));
  10.         }
  11.     }
  12.    
  13.     /* Copie un quadrilatère sur un autre */‘x1’ => $frompxls[0]+$pct*$fromdxup, ‘y1’ => $frompxls[1]+$pct*$fromdyup,
  14.                                      ‘x2’ => $frompxls[6]+$pct*$fromdxdw, ‘y2’‘x1’ => $topxls[0]+$pct*$todxup, ‘y1’ => $topxls[1]+$pct*$todyup,
  15.                                    ‘x2’ => $topxls[6]+$pct*$todxdw, ‘y2’"../capucine.jpg"

Et une version plus aléatoire:

Exemple aléatoire de distortion

Pour obtenir cette dernière version, remplacer le tableau reprenant les coordonnées des sommets de destination de l’image par ceci:

  1.  

Notez que cette version procédurale utilise une partie de ma classe image.class.php pour les parties classiques de gestion d’images.

Alors, cela vous plait?

Tags: , , , ,

3 commentaires pour “Distortion d’images”

  1. yannick dit :

    Le résultat est chouette 🙂

    Dommage qu’il faille se connecter pour poster un commentaire aussi court 😉

  2. Sébastien dit :

    Bah… Disons simplement que la prochaine fois, ce sera plus rapide! :p

  3. yannick dit :

    Sinon, ta classe image.class.php, tu l’as déposée quelque part sur ce site ?