C.git.SDL2.Créer une librairie de manipulation d’images en niveaux de gris. Cette librairie devra permettre d’effectuer les opérations suivantes:
Pour ce travail, en plus de la réalisation de la librairie de
traitement d’images, vous devez utiliser le logiciel de gestion de
version git et évidemment compiler le projet à l’aide d’un
Makefile.
Un grand nombre des fonctions de ce travail peuvent échouer. Pour
simplifier, nous nous limiterons à deux retour possibles du type énuméré
pgm_result:
typedef enum _pgm_result {
success, failure
} pgm_result;Dans ce travail pratique, une image n’est rien d’autre qu’une matrice
de nombres entiers, au sens de celles que vous avez implémentées au
précédent travail pratique. Pour simplifier les images seront uniquement
représentées en niveaux de gris. Ainsi chaque élément de la
matrice représente un pixel. Les valeurs des pixels devront être
limitées entre 0 et une valeur maximale
max.
Pour simplifier encore, les images seront supposées être données au format PGM. Le format PGM (portable graymap file format) est un format de fichier très simple permettant de stocker des images en niveau de gris. Nous utiliserons le format PGM binaire. Vous trouverez une définition du format sur la page https://fr.wikipedia.org/wiki/Portable_pixmap.
Une image PGM peut être représentée à l’aide de la structure de données suivante:
typedef struct _pgm {
int32_t max;
matrix pixels;
} pgm;Le format PGM binaire implique la lecture dans un premier temps d’une
entête contenant le texte P5 sur la première ligne, puis
les dimensions de l’image sur la deuxième ligne. Sur la troisième ligne
se trouve le niveau de gris maximal. Ces trois lignes sont en format
ASCII. Finalement, les pixels de l’image en format binaire
sont stockés dans les lignes restantes. A nouveau pour simplifier, nous
supposerons que chaque pixel est un entier non signé d’un octet.
Nous supposerons dans ce travail, pour simplifier, qu’il n’existe pas
de commentaires dans les fichier (pas de lignes commençant par
#).
Afin de lire et écrire un fichier binaire, il faut utiliser le type pointeur de fichier:
FILE *f;et les fonctions permettant de manipuler les fichiers:
fopen()
avec les option r et w pour ouvrir un fichier
en mode lecture ou écriture.fclose()
pour fermer un fichier.fprintf()
pour écrire le nombre de lignes et de colonnes de l’image, ainsi que
max (voir la définition du format PGM) qui sont au format
ASCII.fgets()
pour lire une ligne d’un fichier au format ASCII (utile pour récupérer
le nombre de lignes, colonnes, ainsi que max).fwrite()
et fread()
pour lire et écrire des données contiguës en mémoire dans un
fichier.A l’aide de ces fonctions vous devriez être capables de lire et écrire des fichiers PGM.
Afin de tester vos fonctions vous pouvez utiliser l’image du mandrill (voir fig. 1.1) en cliquant sur ce lien
Il faut implémenter au minimum les fonctions suivantes:
la fonction
pgm_result pgm_read_from_file(pgm *p, char *filename);lisant le fichier filename et écrivant son contenu dans
la variable p. Cette fonction retourne un
pgm_result.
la fonction
pgm_result pgm_write_to_file(pgm *p, char *filename);écrivant le contenu de l’image p dans le le fichier
filename. Cette fonction retourne un
pgm_result.
Le négatif d’une image consiste à inverser la valeur des
pixels de l’image par rapport à la valeur maximale permise. Ainsi si on
représente max niveaux de gris, le négatif d’un pixel de
niveau de gris, p, est donné par max-p. Un
exemple de négatif de l’image du mandrill se trouve sur la fig. 2.1
Il faut implémenter au minimum la fonction suivante:
la fonction
pgm_result pgm_negative(pgm *neg, pgm *orig);calculant le négatif de l’image orig et la stockant dans
neg (qui est également allouée dans cette fonction).
L’image orig n’est pas modifiée. Cette fonction retourne un
pgm_result.
Une symétrie verticale ou horizontale consiste à inverser l’ordre des pixels verticalement ou horizontalement respectivement. La symétrie centrale consiste à échanger les lignes et les colonnes d’une image. Vous pouvez voir un exemple de ces trois symétries aux fig. 2.2, fig. 2.3, fig. 2.4