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 celle­ci. 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[i­1][j­1]*M[0] + P[i­1][j]*M[1] + P[i­1][j+1]*M[2] + P[i][j­1]*M[3] + P[i][j]*M[4] + P[i­1][j+1]*M[5] + P[i+1][j­1]*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