Consignes

Votre « note de TD » pour ce cours sera basée sur ce devoir à la maison. Il s'agit d'une espèce de petit TP, à renvoyer à votre encadrant de TD (Thomas.Seiller@univ-savoie.fr). Vous devrez envoyer un fichier Python valide, et vous pouvez travailler en petit groupes (au plus quatres personnes). 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. ...

N'oubliez pas de préciser les noms de tous les membres du groupe dans le fichier que vous enverrez...

Liens utiles

1. Les images : rectangles et disques en pixels

1.1. Mini bibliothèque fournie

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

Les seules opérations possibles sur une image sont :

On peut également obtenir des information sur une image avec :

Voici par exemple un morceau de programme Python (fichier test.py) qui définit fonction rectangle puis déclare une image, utilise la fonction rectangle et sauvegarde le résultat dans un fichier test1.ppm.

from images import *

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.
"""
    for x in range(x0, x0+largeur):
        for y in range(y0, y0+hauteur):
            image.change_pixel(x, y, couleur)

## création d'une image couleurs de 200 pixels de large et 150 pixels de haut
image = Image("PPM", 200,150)
## Note : pour créer une image en niveaux de gris, il faudrait mettre "PGM"
## en premier argument

## création d'un carré rouge dans l'image
rectangle(image, 50,35, 75,75, (255,0,0))
## Note 1 : chaque couleur est décomposée en trois : une composante rouge, une
## composante verte et une composante bleue. Chaque composante est un entier
## entre 0 et 255. Le rouge est donc (255,0,0), le vert est (0,255,0) etc.
## Le jaune est (255,255,0). 
## Note 2 : pour une image en niveaux de gris, chaque gris est représenté par un
## unique entier entre 0 (noir) et 255 (blanc).

## création d'un rectangle violet
rectangle(image, 100,20, 35,50, (143, 0, 255))

## sauvegarde de l'image dans un fichier
image.sauve("test1")
## Note : l'extension (".pgm" ou ".ppm" est automatiquement ajoutée)

Si vous executez ce programme, vous devriez voir un nouveau fichier apparaitre dans le repertoire : "test.ppm". C'est une image :

l'origine est toujours en haut à gauche d'une image ; autrement dit, l'axe des y est inversé par rapport aux conventions mathématiques usuelles.

1.2. Rectangles

La méthode image.change_pixel(x,y,couleur) peut échouer si les coordonnées (x,y) désignent un pixel en dehors de l'image.

La fonction rectangle peut donc échouer si le rectangle est mal positionné.

Corrigez la fonction rectangle pour qu'elle ne changent que les pixels dans l'image...

En vous inspirant de la fonction rectangle, écrivez une fonction rectangle_creux(image, x0,y0, largeur,hauteur, couleur) qui dessine le tour d'un rectangle dans une image.

1.3. Disques

Le disque de centre (x0,y0) et de rayon r est donné par l'ensemble des points (x,y) qui vérifient (x-x0)*(x-x0) + (y-y0)*(y-y0) <= r*r.

Écrivez une fonction disque(x0,y0,r,couleur) qui permet de dessiner un cercle dans l'image.

Par exemple :


...

image = Image("PPM", 200,150)

rectangle(image, 50,35, 75,75, (255,0,0))
rectangle(image, 100,20, 35,50, (143, 0, 255))

## création d'un disque
disque(image, 100,100, 40, (0,128,128))

image.sauve("test2")

donnera l'image

2. Transparence

Nous allons maintenant nous restreindre aux images en niveau de gris :

Le test suivant


image = Image("PGM", 400,400)

rectangle(image, 40,300, 160,80, 185)
rectangle(image, 10,280, 60,60, 165)
rectangle(image,30,190, 190,60, 135)
rectangle(image, 230,100, 120,80, 125)
rectangle(image, 100,130, 200,190, 195)
rectangle(image, 130,40, 30,300, 185)
rectangle(image, 220,250, 90,100, 85)
rectangle(image, 250,140, 20,160, 155)

image.sauve("test3")

donne l'image suivante :

On aimerait bien gérer la transparence et faire que deux gris superposés donnent un gris plus foncé. Autrement dit, on aimerait bien obtenir l'image suivante :

Écrivez une nouvelle fonction rectangle_transparent(image, x0,y0, largeur,hauteur, gris) qui permettra d'obtenir l'image précédente.

Attention : vérifiez bien que l'image obtenue sur l'exemple précédent correspond bien à l'image.

Écrivez une fonction similaire disque_transparent(image x0,y0, rayon, gris).