« Pygame/Introduction au module Surfarray » : différence entre les versions

Contenu supprimé Contenu ajouté
Tavernierbot (discussion | contributions)
m Robot : ajoute Catégorie:Pygame (livre)
NewBorn (discussion | contributions)
Avertissement compatibilité Surfarray - Import images - Diverses corrections
Ligne 5 :
 
{{Remarqueampoule|1=''Note du traducteur'' :<br/>
Le projet [http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=1351 Numeric], auquel il est fait référence dans ce tutoriel, a engendré le projet [http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=32367 Numarray], qui lui-même a engendré le projet [http://numpy.scipy.org/ NumPy], lequel est maintenant intégré au projet [http://www.scipy.org/ SciPy] (ouf!). D'après quelques lectures ([http://wiki.python.org/moin/NumericAndScientific 1], [http://numpy.scipy.org//#older_array 2], [http://sourceforge.net/project/showfiles.php?group_id=1369 3]), NumPy '''''devrait''''' être entièrement compatible avec les 2 projets précédents. A vérifier également la compatibilité de Pygame avec NumPy.}}
 
Pygame, quant à lui, est compatible uniquement avec l'ancien projet [http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=1351 Numeric] qui est toujours disponible au téléchargement ainsi que sa documentation ([http://numpy.scipy.org/numpydoc/numdoc.htm HTML] - [http://numpy.scipy.org/numpy.pdf PDF]).}}
 
== Introduction ==
Ligne 11 ⟶ 13 :
Ce tutoriel a pour objectif d'introduire les utilisateurs à Numeric et au module Surfarray de Pygame. Pour les débutants, le code utilisé par Surfarray peut être légèrement intimidant. Mais ici, il y a seulement quelques concepts à comprendre et vous serez opérationnel. En utilisant le module Surfarray, il devient possible de réaliser des opérations au niveau du pixel en utilisant du code python pur. Les compétences requises pour faire cela en C sont d'un niveau beaucoup plus difficilement accessible.
 
Vous pouvez avoir envie d'aller directement voir à la section [[Pygame/Introduction au module Surfarray#Exemples|Exemples]] pour vous faire une idée sur ce qu'il est possible de faire avec ce module, ensuite nous commençeronscommencerons par le début pour vous montrer la manière d'y arriver.
 
Maintenant, je ne vais pas essayer de vous flouer en vous faisant penser que tout est simple. L'obtention d'effets puissants en modifiant les valeurs de chaque pixels est très complexe. Commencer à maîtriser Numeric constitue déjà un apprentissage ardu. Dans ce tutoriel, je serai rapide avec ce qui est facile et je vais utiliser beaucoup d'exemples avec pour objectif de semer les graines de la connaissance. Après avoir fini la lecture de ce tutoriel, vous devriez comprendre les bases du fonctionnement de Surfarray.
Ligne 44 ⟶ 46 :
array([4, 6, 8])
>>> array((1,2,3)) + array((3,4)) #Ajout de tableau de tailles différentes
Traceback (innermostmost recent call last):
File "&lt;interactive input&gt;<stdin>", line 1, in ?<module>
ValueError: frames are not aligned
</source>
Ligne 140 ⟶ 142 :
En utilisant ces tableaux de surface, il y a deux moyens de représenter les valeurs des pixels. La première, peut être de les représenter comme un carte de nombre entiers. Ce type de tableau est un simple tableau 2D avec un unique entier qui représente la couleur du pixel correspondant. Ce type de tableau est pratique pour déplacer des parties d'une image. L'autre type de tableaux utilise trois valeurs pour représenter chaque pixel en codage RGB. Ce type de tableau rend extrêmement simple la réalisation d'effets qui modifie la couleur de chaque pixel. Ce type de matrice est également un peu délicat à manipuler, puisqu'il s'agit en fait d'un tableau à 3 dimensions. Si vous parvenez malgré tout à comprendre le truc, ce n'est pas plus difficile que d'utiliser un tableau 2D normal.
 
Le module Numeric utilise une machine de nombres naturels pour représenter les données numériques, donc un tableau Numeric peut être constitué d'entier de 8bits, 16bits, et 32bits. (les tableaux peuvent également utiliser d'autres types comme des flottants et des doubles, mais pour notre manipulation d'image nous n'utilisons partiquementpratiquement que des entiers). Du fait de la limitation en taille de certains entiers, vous devez veiller à ce que les tableaux contenant les données des pixels soient des tableaux dont les données sont du type adéquat. Les fonctions fabriquant ces tableaux à partir de surfaces sont :
 
*;surfarray.pixels2d(surface)
<source lang="python">
surfarray.pixels2d(surface)
</source>
:Crée un tableau 2D (valeur des pixels entière) qui '''référence''' les données originales de la surface. Ceci fonctionnera pour tous les formats de surface excepté celles en 24 bits.
 
*;surfarray.array2d(surface)
<source lang="python">
surfarray.array2d(surface)
</source>
:Crée un tableau 2D (valeur des pixels entière) '''copié''' depuis n'importe quel type de surface.
 
*;surfarray.pixels3d(surface)
<source lang="python">
surfarray.pixels3d(surface)
</source>
:Crée un tableau 3D (valeur des pixels codé en RGB) qui '''référence''' les données originales d'une surface. Cela va fonctionner exclusivement avec des surfaces sur 24 bits ou 32 bits qui ont un formatage RGB et BGR.
 
*;surfarray.array3d(surface)
<source lang="python">
surfarray.array3d(surface)
</source>
:Crée un tableau 3D (valeurs des pixels codé en RGB) '''copié''' depuis n'importe quel type de surface.
 
Ligne 208 ⟶ 202 :
</source>
 
[[Image:Pygame-allblack.png|left]]
[http://www.pygame.org/docs/tut/surfarray/allblack.jpg Image exemple : allblack.jpg]
 
Dans notre premier exemple, nous créons un tableau entièrement noir de 128 lignes sur 128 colonnes. Pour créer un tableau numérique avec un taille déterminée, il est préférable d'utiliser la fonction <tt>N.zeros()</tt>. Ici, le tableau de zérozéros forme une surface noire.
<br style="clear:both;" />
 
Ligne 222 ⟶ 216 :
</source>
 
[[Image:Pygame-striped.png|left]]
[http://www.pygame.org/docs/tut/surfarray/striped.jpg Image exemple : striped.jpg]
 
Ici nous manipulons un tableau à 3 dimensions. On commence par créer une image rouge. Ensuite nous extrayons une ligne sur trois et nous lui donnons la couleur bleu/vert. Comme vous pouvez le constater, nous pouvons traiter les tableaux à trois dimensions presque comme un tableau à deux dimensions, seulement on lui assigne des 3-uplets au lieu de valeurs uniques (scalaires).
Ligne 235 ⟶ 229 :
</source>
 
[[Image:Pygame-imgarray.png|left]]
[http://www.pygame.org/docs/tut/surfarray/imgarray.jpg Image exemple : imgarray.jpg]
 
Ici nous chargeons une image avec la fonction <tt>image.load()</tt> qui la convertit en un tableau 2D d'entiers. Nous utiliserons cette image comme base dans le reste de nos exemples.
Ligne 247 ⟶ 241 :
</source>
 
[[Image:Pygame-flipped.png|left]]
[http://www.pygame.org/docs/tut/surfarray/flipped.jpg Image exemple : flipped.jpg]
 
Voici un retournement vertical de l'image, réalisé en utilisant la notation en ''slices'' à l'aide d'un incrément négatif pour l'indice des colonnes.
Ligne 259 ⟶ 253 :
</source>
 
[[Image:Pygame-scaledown.png|left]]
[http://www.pygame.org/docs/tut/surfarray/scaledown.jpg Image exemple : scaledown.jpg]
 
Diminuer une image repose sur le même principe que l'exemple précédent. Ici, la notation en slices est utilisée pour conserver seulement un pixel sur deux à la fois verticalement et horizontalement.
Ligne 275 ⟶ 269 :
</source>
 
[[Image:Pygame-scaleup.png|left]]
[http://www.pygame.org/docs/tut/surfarray/scaleup.jpg Image exemple : scaleup.jpg]
 
Augmenter la taille d'une image n'est pas aussi radicalement simple, mais s'inspire de la diminution que nous avons réalisé en utilisant les slices. D'abord, nous créons un tableau qui est de deux fois la taille de l'original. On réalise une copie du tableau original, pixel par pixel, en écrivant seulement sur les colonnes paires du tableau de destination, puis on réalise à nouveau l'opération en écrivant seulement sur les colonnes impaires du tableau de destination. A ce stade, nous avons image redimensionnée correctement, mais toutes les lignes impaires sont noires. Il nous suffit alors de recopier chaque ligne paire sur la ligne du dessous. On obtient ainsi une image dont la taille a doublé.
Ligne 289 ⟶ 283 :
</source>
 
[[Image:Pygame-redimg.png|left]]
[http://www.pygame.org/docs/tut/surfarray/redimg.jpg Image exemple : redimg.jpg]
 
Retour vers les tableaux 3D, on utilisera le codage RGB pour modifier les couleurs. On fait un simple tableau 3D à partir de l'image originale, en utilisant la méthode <tt>surfarray.array3D()</tt>, puis toutes les valeurs pour le bleu et le vert sont mises à zéro. Il nous reste alors, uniquement le canal rouge.
Ligne 306 ⟶ 300 :
</source>
 
[[Image:Pygame-soften.png|left]]
[http://www.pygame.org/docs/tut/surfarray/soften.jpg Image exemple : soften.jpg]
 
On réalise ici une convolution à l'aide d'un filtre 3x3 qui va adoucir les reliefs de l'image. Cela paraît lourd en calculs, mais ce qui est fait est en fait de décaler l'image de 1 pixel dans toutes les directions, et de sommer toutes ces images (en multipliant par un certain coefficient de poids). Alors, on moyenne toutes les valeurs obtenues. Ce n'est pas un filtre gaussien, mais c'est rapide.
 
<br style="clear:both;" />
 
Ligne 322 ⟶ 317 :
</source>
 
[[Image:Pygame-xfade.png|left]]
[http://www.pygame.org/docs/tut/surfarray/xfade.jpg Image exemple : xfade.jpg]
 
Enfin, Nous réalisons une décoloration croisée entre l'image originale et une fond entièrement en bleu. Ce n'est pas très folichon, mais l'image de destination peut être n'importe quoi, et en modifiant le coefficient multiplicateur (0.50 dans l'exemple), vous pouvez choisir chaque étape pour un fondu linéaire entre deux images.
Ligne 341 ⟶ 336 :
Le module Surfarray possède plusieurs méthodes pour accéder aux valeurs du canal alpha/couleur clé d'une surface. Aucune des fonctions qui gèrent le canal alpha, n'a d'effet sur le reste des données de la surface, uniquement sur les valeurs du canal alpha des pixels. Voici la liste de ces fonctions :
 
*;surfarray.pixels_alpha(surface)
:Crée un tableau 2D de valeurs entières qui '''référence''' les valeurs du canal alpha des pixels d'une surface. Ceci fonctionne uniquement avec les images codées sur 32 bits par pixel, avec un canal alpha sur 8 bits.
 
*;surfarray.array_alpha(surface)
:Crée un tableau 2D de valeurs entières qui '''copie''' les valeurs du canal alpha des pixels d'une surface. Ceci fonctionne avec tous les types de surface. Si l'image d'origine ne contient aucun canal alpha, les valeurs du tableau sont initialisées à 255, qui est la valeur maximale d'opacité.
 
*;surfarray.array_colorkey(surface)
:Creates a 2D array (integer pixel values) that is set to transparent (0) wherever that pixel color matches the Surface colorkey. Crée un tableau 2D de valeurs entières qui met la transparence à 0 (valeur maximale de transparence) pour chaque pixel de la surface dont la couleur correspond à la couleur clé.
 
== Autres fonctions du module Surfarray ==
Ligne 354 ⟶ 349 :
Il existe quelques autres fonctions disponibles dans le module Surfarray. Vous pouvez en obtenir une liste exhaustive ainsi qu'une description plus complète sur la page de [http://pygame.seul.org/docs/ref/surfarray.html référence]. Notez malgré tout cette fonction très utile :
 
*;surfarray.blit_array(surface, array)
:Ceci va transférer tout type de tableau 2D ou 3D sur une surface possédant les mêmes dimensions. Ce blit de Surfarray sera généralement beaucoup plus rapide que d'assigner un tableau qui contiendrait les pixels de référencesréférence. Néanmoins, ça ne devrait pas être plus rapide qu'un blit normal d'une surface, puisque celui-ci est très optimisé.
:This will transfer any type of 2D or 3D surface array onto a Surface of the same dimensions. This surfarray blit will generally be faster than assigning an array to a referenced pixel array. Still, it should not be as fast as normal Surface blitting, since those are very optimized.
Ceci va transférer tout type de tableau 2D ou 3D sur une surface possédant les mêmes dimensions. Ce blit de Surfarray sera généralement beaucoup plus rapide que d'assigner un tableau qui contiendrait les pixels de références. Néanmoins, ça ne devrait pas être plus rapide qu'un blit normal d'une surface, puisque celui-ci est très optimisé.
 
== Utilisation plus avancée de Numeric ==