Sujet TP 3
Transcription
Sujet TP 3
Langage C
TP n°3 ‐ Structures, Lecture et écriture
Pour ce TP, vous allez réaliser et utiliser votre propre librairie de manipulation d’image au format PPM (Portable Pixel Map). Le format Portable Pixel Map
Le format PPM est un format de stockage d’images dans lequel chaque pixel est stocké sous la forme d’un ensemble de
3 valeurs entières RGB (Red, Green, Blue)
. Un fichier PPM possède une structure très simple : il commence par un
“nombre magique” (
P6 ou
P3
selon le mode d’enregistrement), suivi d’un
nombre de colonnes
, d’un
nombre de lignes
, d’une
valeur de couleur maximale comprise entre 1 et 65536 (2^16 soit 2 octets), et d’une
suite de valeurs RGB entre 0 et la valeur maximale d’une composante. Chacune de ces informations doit être suivie d’un “
whitespace
” (un espace ou un retour à la ligne). Voici un petit exemple de fichier PPM tiré de wikipédia : P3 # Le P3 signifie que les couleurs sont en ASCII, 3 2 # par 3 colonnes et 2 lignes, 255 # ayant 255 pour valeur maximum. # Le tableau des composantes de couleur 255 0 0 0 255 0 0 0 255 255 255 0 255 255 255 0 0 0 Pour plus d’informations sur ce format, vous pouvez consulter la page de manuel : http://netpbm.sourceforge.net/doc/ppm.html Préparation de la bibliothèque
1. Créez vos fichiers
libMyPPM.h
et
libMyPPM.c 2. Créez dans votre header une structure
Pixel contenant 3
entiers courts non signés représentant les valeurs R, G, et B. 3. Créez également une structure
ImagePPM
permettant de décrire une image PPM. La liste de couleur sera représentée par un pointeur vers un tableau de
Pixels
. On ignorera le magic number (nous utiliserons P3 par défaut) Les fonctions essentiels
1. Créez une fonction
newPixel qui prend en paramètres 3 entiers courts non signés et renvoi le
Pixel
correspondant. 2. Créez une fonction
newImagePPM
prenant en paramètre une largeur, une hauteur et une valeur maximale de composante, qui renvoie une
ImagePPM
correspondante. Chaque
Pixel
devra être initialisé à
(0,0,0)
. 3. Créez une fonction
displayImagePPM
prenant en paramètre une
ImagePPM
et affichant dans le terminal les valeurs contenues dans celleci. 4. Créez une fonction
damierPPM
renvoyant une
ImagePPM
de taille 1024 par 1024, composée de 8 x 8 carrés noirs (0,0,0) et blancs (255,255,255), en alternant les carrés noirs et les carrés blancs. 5. Testez chacune de vos fonctions dans un main
en dehors
de la librairie. Lecture et enregistrement d’un exemple
1. Créez une fonction
saveImagePPM
prenant en paramètre une
ImagePPM un nom de fichier sous la forme
const char* et enregistrant votre image dans le fichier correspondant. 2. Créez une fonction
loadImagePPM
prenant en paramètre un nom de fichier sous la forme const char* et retournant l’
ImagePPM
correspondante. Attention, le format PPM gère également les commentaires par ligne : tout élément situé après un # sur une ligne doit être ignoré. 3. Tester vos fonctions en essayant d’enregistrer et de recharger le résultat de votre fonction
damierPPM
. Manipulation d’images
1. Créez une fonction
inverseImagePPM
prenant en entrée une
ImagePPM
et retournant cette image avec chaque valeur R G B inversée (C = max C). 2. Créez une fonction
rotateImagePPM90
prenant en entrée une
ImagePPM
et retournant cette image tourner a 90° dans le sens inverse des aiguilles d’une montre. Faites bien attention aux valeurs de largeur et de hauteur. 3. Créez une fonction
convolvePPMWith1DMatrix
prenant en entrée une
ImagePPM
, un tableau
M
de 9 réels et un réel
D
et renvoyant une
ImagePPM
sur laquelle la formule suivante serait appliqué sur chaque composante de
Pixel
de l’image : P[i][j] = ( P[i1][j1]*M[0] + P[i1][j]*M[1] + P[i1][j+1]*M[2] + P[i][j1]*M[3] + P[i][j]*M[4] + P[i1][j+1]*M[5] + P[i+1][j1]*M[6] + P[i+1][j]*M[7] + P[i+1][j+1]*M[8] ) / D ; 4. Testez cette dernière fonction successivement avec un diviseur égale a 1 et les tableaux
{1, 0, 1, 2, 0, 1, 1, 0, 1}
et
{1, 2, 1, 0, 0, 0, 1, 2, 1} 5. Ces matrices sont ce que l’on appel des noyaux de convolution, qui permettent de réaliser de nombreux effets pour transformer une image en utilisant les pixels voisins de chaque pixel de l’image. Essayez par exemple de trouver un filtre permettant d’ajouter un flou sur l’image. Suppléments :
compiler et utiliser une librairie dynamique
En informatique, une manière courante de partager son travail sans forcément révéler son code consiste à compiler son code en librairie statique ou dynamique. Tout d’abord, il faut précompiler votre code de librairie avec l’option fpic gcc c Wall fpic libMyPPM.c On génère ensuite la librairie dynamique lib***.so à partir du ou des fichiers compilés : gcc shared libMyPPM.o o libMyPPM.so Ou la librairie statique lib***.a ar cvq libMyPPM.a libMyPPM.o ar t libMyPPM.a Une fois la librairie compilée, vous pouvez la réutiliser en ajoutant les directives suivantes à votre commande de compilation : L<Dossier/de/votre/lib contenant le .so ou le .a> lMyPPM I<Dossier/de/votre/lib contenant le ou les .h> par exemple : gcc L/home/Projects/MyPPM/lib lMyPPM I/home/Projects/MyPPM/include main.c