Consignes

Vous devrez utiliser l'interface TPLab pour envoyer vos TP aux encadrants de TP.

La note ne valide pas seulement le résultat de votre programme, mais également son style :

Vérifiez ces points avant de demander à votre intervenant de valider votre code.

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

Liens utiles

1. Images, utiliser la bibliothèque fournie

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 sous Windows, vous pouvez installer de petit utilitaire IrfanView téléchargeable ici.

Si vous utilisez Linux les images devraient être reconnues automatiquement.

La petite bibliothèque images.py permet de créer, ouvrir, modifier et sauver des images simples aux format "PBM", "PGM" ou "PPM". Vous devez télécharger le fichier images.py et le mettre dans le même répertoire que votre propre fichier.

Voici par exemple un morceau de programme Python qui déclare une image, dessine un point gris au milieu et sauve l'image dans "test.pgm":

from images import *

image = Image("PGM", 7, 11)
change_pixel(image, largeur(image)//2, hauteur(image)//2, 127)
sauve(image, "test")

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

  1. image = Image("PGM",7,11) : on initialise une image image. Les 3 arguments obligatoires sont :
    • le type d'image : "PBM" (noir et blanc), "PGM" (niveaux de gris) ou "PPM" (couleurs),
    • les dimensions largeur (ici, 7 pixels) et hauteur (ici, 11 pixels),
    On peut également donner un quatrième argument pour la couleur de fond de l'image. (blanc par défaut)

  2. change_pixel(image, x, y, couleur) est un appel à un procédure qui permet de changer la couleur d'un pixel. (//Attention, le point (0,0) est en haut à gauche.) Ici, la couleur est 127, c'est à dire gris. En général, la couleur doit être :
    • 0 (blanc) ou 1 (noir) pour une image PBM (noir et blanc),
    • un entier entre 0 (noir) et 255 (blanc) pour une image PGM (niveaux de gris),
    • un triplet d'entiers entre 0 et 256 pour une image PPM (couleurs). Chaque entier représente une composante : rouge, vert et bleu. Par exemple, (255, 215, 0) contient seulement du rouge (255) et du vert (215), ce qui donne un ton de jaune.

  3. largeur(largeur) permet de récupérer la largeur de l'image lorsque l'on ne l'a pas créée nous même. Dans notre cas, largeur(image) donne simplement 7. hauteur(image) est la hauteur de l'image...

  4. sauve(image, nom) est une autre procédure. Elle permet de sauvegarder l'image dans un fichier. Attention :
    • nom doit être une chaîne de caractères,
    • l'extension du fichier est ajoutée automatiquement : dans ce cas, le nom du fichier sera test.pgm.

Remarques : vous pouvez obtenir un petit message d'aide pour chaque fonction avec "help(nom_de_la_fonction)".

2. Rectangles

  1. Téléchargez le fichier squelette, changer le nom du fichier et modifiez la valeur de la variable nom tout en haut du fichier...

  2. N'oubliez pas de télécharger également la petite bibliothèque images.py que vous devrez sauvegarder dans le même répertoire que votre fichier tp1-___.py.

  3. Pour ce TP, vous devez écrire des fonctions, et les tests sont fait automatiquement par la fonction tests_tp1(). Autrement dit, à chaque modification, vous devrez sauvez votre fichier et le charger dans Idle (avec la touche F5 par exemple). La fonction de test sera automatiquement lancée... (Vous pouvez modifier les tests dans la fonction appropriée si vous le souhaiter...)

Écrivez le corps de la procédure suivante :

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

Attention : cette procédure modifie une image existante qui lui est passé en paramètre. La procédure rectangle ne crée pas une nouvelle image et n'utilise donc ni la fonction "Image(...)" ni la méthode "save". C'est la procédure de test qui le fait...

Vérifiez que votre fonction fait ce qu'il faut en :

3. Disques et cercles

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

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

Rappel : le disque de centre (x0,y0) et de rayon R est constitué de l'ensemble des points de coordonnées (x,y) qui vérifient (x-x0)2 + (y-y0)2 ≤ R2.

Essayez maintenant de dessiner un cercle sur une image :

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

Rappel : le disque de centre (x0,y0) et de rayon R est constitué de l'ensemble des points de coordonnées (x,y) qui vérifient (x-x0)2 + (y-y0)2 = R2.

Testez votre fonction et commentez ce que vous voyez et essayer de corriger.

4. Dégradés

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

Le cas le plus simple est un rectangle dégradé en gris qui va du noir au blanc. Un rectangle de 256 pixels de haut aura sa ligne i au niveau de gris i. Ainsi, la première ligne aura le gris 0 (noir) et la ligne 255 aura le gris 255 (blanc).

Lorsque le rectangle a une hauteur de 128 pixels, la ligne i aura le niveau de gris 2 * i et lorsque le rectangle a une hauteur de 512 pixels, la ligne i du rectangle à la couleur i // 2.

Lorsqu'on doit créer un dégradé entre deux couleurs arbitraire, il y a plusieurs difficultés supplémentaires :

Écrivez 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.
    """

Consignes : expliquez (en commentaires) comment vous faites pour calculer la couleur d'un point du rectangle.

Voici un exemple de résultat :

>>> im = Image("PPM", 100,100, (0,0,0))
>>> rectangle_degrade(im, 25,30, 45, 70, (0,200,0), (0,20,127))
>>> sauve(im, "test-degrade")

5. Segments (difficile)

Programmez la procédure

def segment(image, x1, y1, x2, y2, couleur):
    """Dessine un segment dans l'image "image".
    Les arguments "x1", "y1" et "x2","y2" désignent les coordonnées des
    extrémités du segment.
    """

Par exemple :

>>> im = Image("PBM", 50, 50, 1)
>>> segment(im, 0,0 , 49,13 , 0)
>>> sauve(im, "test-segment")

donne :

6. Art moderne ??

En utilisant le module random, écrivez une procédure 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 procédure doit créer une nouvelle image. Elle doit donc faire un "im = Image(...)" et un "sauve(im,...)".