Vous avez jusqu'à la fin de la journée pour m'envoyer votre TP par email (pierre.hyvernat@univ-savoie.fr)

Consignes

Pour ce TP, la pièce la plus importante sera un fichier tp1-nom1-nom2.py contenant votre programme. Le seul fait que votre programme fonctionne ne suffit pas pour avoir une bonne note. Les points suivants seront pris en compte :

  1. la lisibilité de votre programme (choix pertinent pour les noms de variables etc.),
  2. la présence de commentaires aux endroits appropriés,
  3. ...

Ce n'est pas obligatoire, mais je vous conseille fortement d'utiliser le fichier squelette fourni comme point de départ. Ce fichier contient les déclarations des fonctions ainsi qu'une fonction "tp1()" qui permettra de tester vos fonctions. (Vous pouvez facilement modifier cette fonction de test pour faire ce que vous voulez...)

Certaines questions appellent à une réponse que vous pouvez mettre en commentaire dans votre fichier tp1-nom1-nom2.py. Si vous le souhaitez, vous pouvez aussi m'envoyer un rapport de TP. Le format de ce rapport sera au choix, mais par ordre de préférence :

Attention : les points suivants ne rapportent rien, mais ne pas les respecter pourra retrancher jusqu'à 10 points sur la note finale :

Liens utiles

1. Les images

1.1. Formats Netpbm

Il existe des bibliothèques pour manipuler des images complexes, mais pour ce TP, nous n'utiliserons que des images dans des formats très simples : Netpbm « plain ». Ces images sont stockées en ASCII, ce qui les rend lisibles sans aucun outils spécialisés.

Par exemple, voici une image noir et blanc contenant un petit carré blanc dans un grand carré noir :

P1
10 10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1

Et voici l'image correspondante : "". (Remarque : les formats utilisés pour ce TP ne sont pas très standards, et les navigateurs web ne les affichent en général pas. J'ai donc convertit les images en un format plus courant : PNG.)

Il y a trois formats différents :

1.2. Mini bibliothèque fournie

Pour ce TP, vous utiliserez une mini bibliothèque que vous pouvez télécharger ici. Voici par exemple un morceau de programme Python qui déclare une image, dessine un point au milieu et sauve l'image dans "mon_image.ppm":

from images import im_initialise, im_ouvre, im_sauve, im_change_pixel
from images import im_couleur_pixel, im_hauteur, im_largeur, im_format

largeur = 9
hauteur = 9
im = im_initialise("PGM", largeur, hauteur, 1)
im_change_pixel(im,largeur//2, hauteur//2, 127)
im_sauve(im,"mon_image")

Voici, avec des détails, ce qu'il se passe :

  1. from images import ... : ceci permettra d'accéder aux fonctions de la bibliothèques images,
  2. largeur = 9 et hauteur = 9 : on initialise 2 variables largeur et hauteur
  3. im = im_initialise("PGM", largeur, hauteur, 1) : on initialise une variable im qui dénotera une image. La fonction im_initialise a 3 arguments obligatoires et 1 facultatif :
    • le type d'image : "PBM", "PGM" ou "PPM",
    • les dimensions largeur et hauteur,
    • la couleur initiale de l'image (par défaut : blanc).
  4. im_change_pixel(im,largeur//2, hauteur//2, 127) : on dessine un point aux coordonnées (largeur//2, hauteur//2) en utilisant le gris numéro 127. (Voir plus bas.)
  5. im_sauve(im,"mon_image") : on sauve l'image finale dans le fichier mon_image.pgm.

Remarques :

Attention : les formats d'image utilisés dans ce TP (plain PBM, plain PGM et plain PPM) ne sont pas reconnus nativement par Windows XP. Pour visualiser vos images, vous pouvez installer de petit utilitaire IrfanView téléchargeable ici.

Si vous utilisez Linux sur votre ordinateur personnel (c'est bien) les images devraient être reconnues automatiquement. Par contre, les ordinateurs de l'université n'ont pour le moment que Python-2.5 sur leur partition Linux. Si vous souhaiter utiliser quand même Linux (c'est bien), il suffit de modifier deux lignes (lignes 99 et 101) dans la bibliothèque.

2. Rectangles et dégradés

2.1. Préliminaires

  1. Créez quelques images à la main (en couleurs / gris / noir et blanc) en vous basant sur l'exemple ci-dessus.
  2. Visualisez les images pour faire le lien entre le contenu du fichier et l'image affichée.
  3. Modifiez le contenu du fichier avant de le réafficher.

Que pensez-vous de ces formats d'images (plain PBM, plain PGM et plain PPM) ? Comment pourrait-on les améliorer ?

2.2. Rectangles et carrés

Écrivez le corps de la procédure suivante :

def rectangle(image, x0, y0, largeur, hauteur, couleur):
    """Dessine un rectangle dans l'image "image".
Les arguments "x0" et "y0" désignent le point en haut à gauche du rectangle,
l'argument "largeur" sa largeur, l'argument "hauteur" sa hauteur et l'argument
"couleur" sa couleur.
Attention, si le rectangle ne tient pas dans "image", il ne faudra dessiner
qu'un bout du rectangle..."""

Vérifiez que vous faites ce qu'il faut en :

Attention : cette fonction utilise une image existante et ne fait donc pas de "im_initialise" ou de "im_save". C'est la fonction de test qui fera ceci...

En utilisant la procédure précédente, écrivez une procédure :

def mire (image, couleur, longueur, epaisseur):
    """Dessine une 'mire' (une croix horizontale) au milieu de l'image."""

Voici par exemple ce que ça pourrait donner sur une image couleur à fond gris :

Attention : cette fonction utilise une image existante et ne fait donc pas de "im_initialise" ou de "im_save". C'est la fonction de test qui fera ceci...

2.3. Dégradés

Le but est maintenant de dessiner un rectangle contenant un dégradé vertical.

Écrivez une procédure

def fond_degrade_simple(largeur, nom_image):
    """Crée une image rectangulaire en niveau de gris de taille "largeur" x 256.
Cette image contiendra un dégradé de gris (de blanc en haut à noir en
bas de l'image).
L'image sera sauvegardée dans le fichier "nom_image".pgm.
"""

Attention : cette fonction doit créer une nouvelle image. Elle doit donc faire un "im_initialise" et un "im_save".

Modifiez votre procédure précédente pour obtenir :

def fond_degrade(largeur, hauteur, nom_image):
    """Crée une image rectangulaire en niveau de gris de taille "largeur" x "hauteur".
Cette image contiendra un dégradé de gris (de blanc en haut à noir en
bas de l'image).
L'image sera sauvegardée dans le fichier "nom_image".pgm.
"""

Attention : cette fonction doit créer une nouvelle image. Elle doit donc faire un "im_initialise" et un "im_save".

Attention : il faut que l'image aille du blanc au noir, quel que soit la taille de l'image...

Écrivez maintenant la procédure :

def rectangle_degrade(image, x0, y0, largeur, hauteur, couleur_haut, couleur_bas):
    """Dessine un rectangle dans l'image "image" qui est forcément au format
"PPM" (couleurs RGB).
Les coordonnées du point haut/gauche du rectangle sont "x0" et "y0" ; et ses
dimensions sont "largeur" et "hauteur".
Le rectangle contient un dégradé de couleurs : de "couleur_haut" en haut du
rectangle, jusqu'à "couleur_bas" en bas du rectangle.
"""

Attention : cette fonction utilise une image existante et ne fait donc pas de "im_initialise" ou de "im_save". C'est la fonction de test qui fera ceci...

Consignes :

3. Disques et cercles

Réfléchissez à une méthode pour dessiner un disque plein sur une image. Essayez ensuite de programmer la procédure :

def disque(image, x0, y0, rayon, couleur):
    """Dessine un disque dans l'image "image".
Les arguments "x0" et "y0" designent le centre, l'argument "rayon" le rayon
et "couleur" sa couleur."""

Attention : cette fonction utilise une image existante et ne fait donc pas de "im_initialise" ou de "im_save". C'est la fonction de test qui fera ceci...

Essayez maintenant de dessiner un cercle sur une image :

def cercle(image, x0, y0, rayon, couleur):
    """Dessine un disque dans l'image "image".
Les arguments "x0" et "y0" designent le centre, l'argument "rayon" le rayon
et "couleur" sa couleur."""

Testez votre fonction et commentez ce que vous voyez.

Attention : cette fonction utilise une image existante et ne fait donc pas de "im_initialise" ou de "im_save". C'est la fonction de test qui fera ceci...

4. Art moderne ??

En utilisant le module Random, écrivez une fonction art_moderne qui génère une image aléatoire contenant des disques et des rectangles. Choisissez des arguments pertinents pour pouvoir choisir les paramètres de votre image finale.

Voici un exemple de ce que vous pourriez obtenir :

Attention : cette fonction doit créer une nouvelle image. Elle doit donc faire un "im_initialise" et un "im_save".