diff --git a/.gitattributes b/.gitattributes index 412eeda..705c150 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,11 +12,16 @@ # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain + +# Personalisé +*.pbm binary +*.pgm binary +*.ppm binary \ No newline at end of file diff --git a/src/analyserCommande.cpp b/src/analyserCommande.cpp index 1cc4d7c..0e07d3c 100644 --- a/src/analyserCommande.cpp +++ b/src/analyserCommande.cpp @@ -2,22 +2,6 @@ #include #include -int chaineVersEntier(string chaine, int &entier) { - entier = atoi(chaine.c_str()); - if (entier == 0 && chaine != "0") { - return 1; - } - return 0; -} - -int chaineVersFlottant(string chaine, float &flottant) { - flottant = atof(chaine.c_str()); - if (flottant == 0 && chaine != "0") { - return 1; - } - return 0; -} - void afficherImage(Image image) { int x, y, r, v, b, dimensionX = image.g_dimensionX(), dimensionY = image.g_dimensionY(), typeComposantes = image.g_typeComposantes(); diff --git a/src/main.cpp b/src/main.cpp index 1089307..ddac7b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,75 +4,19 @@ using namespace std; #include "affichageFenetre.cpp" #include "image.h" +#include "utilitaires.cpp" #include "traitementImage.cpp" #include "analyserCommande.cpp" #define NOMBREOR 1.61803398875 -Image imageDefaut() { - int dimY = 256, dimX = dimY * NOMBREOR, maxComposante = 255; - Image imageRoue(dimX, dimY, maxComposante, PILG_RVB); - Pixel pointRoue = imageRoue.g_pixelVide(); - int x, y, step; - float substep, lum; - for (x = 0; x < dimX; x++) { - for (y = 0; y < dimY; y++) { - step = (x * 6.0) / dimX; - substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante; - lum = 1 - ((float) y) / dimY; - switch (step) { - case 0: - pointRoue.r = maxComposante; - pointRoue.v = substep; - pointRoue.b = 0; - break; - case 1: - pointRoue.r = maxComposante - substep; - pointRoue.v = maxComposante; - pointRoue.b = 0; - break; - case 2: - pointRoue.r = 0; - pointRoue.v = maxComposante; - pointRoue.b = substep; - break; - case 3: - pointRoue.r = 0; - pointRoue.v = maxComposante - substep; - pointRoue.b = maxComposante; - break; - case 4: - pointRoue.r = substep; - pointRoue.v = 0; - pointRoue.b = maxComposante; - break; - case 5: - pointRoue.r = maxComposante; - pointRoue.v = 0; - pointRoue.b = maxComposante - substep; - break; - default: - pointRoue.r = pointRoue.v = pointRoue.b = 0; - } - - // Dégradé vers le noir - pointRoue.r = pointRoue.r * lum; - pointRoue.v = pointRoue.v * lum; - pointRoue.b = pointRoue.b * lum; - - imageRoue.s_pixel(x, y, pointRoue); - } - } - return imageRoue; -} - int main(int argc, char *args[]) { #if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL freopen("CON", "w", stdout); freopen("CON", "w", stderr); #endif - cout << "PILG" << endl; // Message d'entrée et de test + presentation(); Image image = imageDefaut(); diff --git a/src/testing.cpp b/src/testing.cpp index 8ab10fc..b799e3f 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -5,6 +5,7 @@ using namespace std; #include "affichageFenetre.cpp" #include "image.h" +#include "utilitaires.cpp" #include "traitementImage.cpp" #include "analyserCommande.cpp" @@ -104,19 +105,29 @@ int main(int argc, char *args[]) { freopen("CON", "w", stderr); #endif - cout << "PILG - Test" << endl; // Message d'entrée et de test - - // Image image = genererRoue(256, 128, 255); + presentation(); #define DIMENSIONS 256 + Image imageOriginale = genererRoue(DIMENSIONS*2, DIMENSIONS, 255); + // Image imageoriginale; // Tester si ça marche - Image imageOriginale = genererRoue(DIMENSIONS, DIMENSIONS, 255); - Image image = imageOriginale.g_vide(); - for (float i = 0; i < 2 * PI; i += 0.1) { - pivoter(imageOriginale, image, DIMENSIONS/2, DIMENSIONS/2, i); - afficherImage(image); - } + // // Roue + // Image image = imageOriginale.g_vide(); + // for (float i = 0; i < 2 * PI; i += 0.1) { + // pivoter(imageOriginale, image, DIMENSIONS/2, DIMENSIONS/2, i); + // afficherImage(image); + // } + // Ouvrir fichier + // cout << ouvrir(imageOriginale, "tests/PikachuP6.ppm") << endl; + + afficherImage(imageOriginale); + attendreFenetre(); + + // pivoter(imageOriginale, imageOriginale, imageOriginale.g_dimensionX()/2, imageOriginale.g_dimensionY()/2, 0.5); + // attendreFenetre(); + + cout << sauver(imageOriginale, "tests/Sauvegardé.ppm", true, "Ceci est un commentaire") << endl; // // Neige en dégradé // for (int i; i < 300; i++) { @@ -157,6 +168,7 @@ int main(int argc, char *args[]) { // } // cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl; + fermerFenetre(); return 0; diff --git a/src/traitementImage.cpp b/src/traitementImage.cpp index 5c64c31..2a06fec 100644 --- a/src/traitementImage.cpp +++ b/src/traitementImage.cpp @@ -1,8 +1,11 @@ #include +#include #define PI 3.14159265359 #define MAXCOMPOSANTEDEFAUT 255 +typedef enum {PILG_TYPE, PILG_DIMENSIONS, PILG_MAXCOMPOSANTE, PILG_IMAGE} PILG_OuvrirEtape; + // Gestion de fichiers int creer(Image &sortie, unsigned int dimensionX, unsigned int dimensionY, unsigned int maxComposante, PILG_Comp typeComposantes) { // Créer une image de dimensions X et Y sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes); @@ -10,13 +13,174 @@ int creer(Image &sortie, unsigned int dimensionX, unsigned int dimensionY, unsig } int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à partir du nom du fichier ***Geoffrey + // Ouverture du fichier + ifstream streamFichier(nomFichier.c_str(), ios::in); + if (streamFichier) { + // Calcul de la taille (en octets) du fichier + streamFichier.seekg(0, ios::end); + int tailleFichier (streamFichier.tellg()); - return 1; + // Stockage du fichier dans une chaîne + streamFichier.seekg(0, ios::beg); + char *caracteres = new char [tailleFichier]; + streamFichier.read(caracteres, tailleFichier); + string fichier_caracteres(caracteres); + delete[] caracteres; + streamFichier.close(); + + // Variables d'informations + PILG_OuvrirEtape ouvrirEtape(PILG_TYPE); + bool ASCII(false); + int dimensionX; + int dimensionY; + int maxComposante; + PILG_Comp typeComposantes; + + // Variables de traitement du fichier + string element(""); + int x(0); + int y(0); + string pixelASCII; + int RVBcomposante(0); // Composante actuelle pour RVB + + for (int c(0); c < tailleFichier; c++) { + if (ouvrirEtape != PILG_IMAGE) { + if (fichier_caracteres[c] == (char) 0x0a) { // En cas de nouvel élément + if (element[0] != '#') { // Si c'est un commentaire, on passe à l'élément suivant + switch (ouvrirEtape) { + case PILG_TYPE: + if (element.length() == 2 && element[0] == 'P') { + switch (element[1]) { + case '1': + case '4': + typeComposantes = PILG_BIN; + break; + case '2': + case '5': + typeComposantes = PILG_NIV; + break; + case '3': + case '6': + typeComposantes = PILG_RVB; + break; + default: + return 3; + break; + } + switch (element[1]) { + case '1': + case '2': + case '3': + ASCII = true; + break; + case '4': + case '5': + case '6': + ASCII = false; + break; + default: + return 3; + break; + } + } else { + return 3; + } + + ouvrirEtape = PILG_DIMENSIONS; +#if DEBUG + cout << "Type de fichier : " << element << " (" << ((typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ? "Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" : "Brut") << ")" << endl; +#endif + break; + + case PILG_DIMENSIONS: { + bool espaceDepasse(false); + string dimensionXchaine(""); + string dimensionYchaine(""); + for (int j(0); j < element.size(); j++) { + if (element[j] == ' ') { + espaceDepasse = true; + } else if (espaceDepasse) { + dimensionXchaine += element[j]; + } else { + dimensionYchaine += element[j]; + } + } + chaineVersEntier(dimensionXchaine, dimensionX); + chaineVersEntier(dimensionYchaine, dimensionY); + if (!espaceDepasse || dimensionX == 0 || dimensionY == 0) { + return 5; + } +#if DEBUG + cout << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" << endl; +#endif + if (typeComposantes == PILG_BIN) { + ouvrirEtape = PILG_IMAGE; + } else { + ouvrirEtape = PILG_MAXCOMPOSANTE; + } + } + break; + case PILG_MAXCOMPOSANTE: + chaineVersEntier(element, maxComposante); +#if DEBUG + cout << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") << " : " << maxComposante << endl; +#endif + ouvrirEtape = PILG_IMAGE; + break; + + default: + return 4; + break; + } + element = ""; + if (ouvrirEtape == PILG_IMAGE) { + sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes); + } + } + } else { + element += fichier_caracteres[c]; + } + } else { + // ... + } + } + } else { + return 1; + } +#if DEBUG + cout << endl << endl; +#endif + + return 0; } int sauver(Image entree, string nomFichier, bool ASCII, string commentaire) { // Sauvegarder l'image obtenue dans un nouveau fichier - - return 1; + ofstream fichier(nomFichier.c_str(), ios::out | ios::trunc); +#define FICHIER_SEPARATEUR (char) 0x0a + if (entree.g_typeComposantes() == PILG_RVB && ASCII) { + fichier << "P6"; + } else { + return 1; + } + fichier << FICHIER_SEPARATEUR; + // if (commentaire) { + // fichier << "#" << commentaire << FICHIER_SEPARATEUR; + // } + fichier << entree.g_dimensionX() << " " << entree.g_dimensionY() << FICHIER_SEPARATEUR; + + if (entree.g_typeComposantes() != PILG_BIN) { + fichier << entree.g_maxComposante() << FICHIER_SEPARATEUR;; + } + Pixel pixel; + for (int x = 0; x <= entree.g_dimensionX(); x++) { + for (int y = 0; y <= entree.g_dimensionY(); y++) { + if (entree.g_typeComposantes() == PILG_RVB && ASCII) { + fichier << pixel.r << FICHIER_SEPARATEUR << pixel.v << FICHIER_SEPARATEUR << pixel.b << FICHIER_SEPARATEUR; + } + } + } + fichier.close(); + return 0; } int importer(Image entree, Image &sortie, string nomFichier, int x, int y) { @@ -34,105 +198,52 @@ int importer(Image entree, Image &sortie, string nomFichier, int x, int y) { // Couleur -int rvbVersTsl(Pixel entree, Pixel &sortie) { - TSLcouleur tslcouleur; - float r = (float) entree.r/entree.maxComposante; - float v = (float) entree.v/entree.maxComposante; - float b = (float) entree.b/entree.maxComposante; - - float min = (r < v < b ? || (v < r && v < b ? b b || v)); - float max = (r > v > b ? || (v > r && v > b ? b b || v)); - float s, h, l; - if max == min - s = 0 - h = Number.NaN - else - s = if l < 0.5 then (max - min) / (max + min) else (max - min) / (2 - max - min) - - if r == max then h = (g - b) / (max - min) - else if (g == max) then h = 2 + (b - r) / (max - min) - else if (b == max) then h = 4 + (r - g) / (max - min) - - h *= 60; - h += 360 if h < 0 - [h,s,l] -} int teinte(Image entree, Image &sortie, float teinte) { // Change la teinte de l'image - for (int x=0, x = image.g_DimensionX(), x++) { - for (int y=0, y = image.g_DimensionY(), y++) { - rvbVersTsl(); - g_pixel(x, y); - - } - } -return 1; + // for (int x = 0, x = image.g_DimensionX(), x++) { + // for (int y = 0, y = image.g_DimensionY(), y++) { + // rvbVersTsl(); + // g_pixel(x, y); + + // } + // } + // return 1; } int saturation(Image entree, Image &sortie, float saturation) { // Sature l'image - // Pour x = image.g_DimensionX() - // Pour y = image.g_DimensionY() - // Ajouter la variable saturation à chaque valeur de chaque pixel - // Ne pas dépasser le seuil limite MaxComposante !!! - // Fin Pour - // Fin Pour + // Utilisation de la méthode TSL return 1; } int luminosite(Image entree, Image &sortie, float luminosite) { // Augmente la luminosité de l'image - // Pour x=0 à x=image.g_DimensionX() - // Pour y=0 à y=image.g_DimensionY() - // si image.g_typeComposante=1 - // pixel = image.g_pixel(x,y); - // pixel.g = luminosite*10+pixel.g; - // image.s_pixel(x, y, pixel); - // sinon si image.g_typeComposante=2 - // pixel = image.g_pixel(x,y); - // pixel.r = luminosite*10+pixel.r; - // pixel.v = luminosite*10+pixel.v; - // pixel.b = luminosite*10+pixel.b; - // image.s_pixel(x, y, pixel); - // Fin si - // Fin Pour - // Fin Pour + // Utilisation de la méthode TSL return 1; } int contraste(Image entree, Image &sortie, float contraste) { // Accentue les contrastes de l'image - // pour x=0 à x=image.g_dimensionX() - // pour y=0 à y=image.g_DimensionY() - // si image.g_typeComposante=1 - // pixel = image.g_pixel(x,y); - // pixel.g = contraste*pixel.g; - // if pixel.g > Image.g_maxComposante - // pixel.g = Image.g_maxComposante - // end if - // End If - // Fin Pour - // Fin Pour - - + // À voir return 1; } // Dessin int trait(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel couleur) { // Dessine un trait d'un point (x1,y1) à un point (x2,y2) - int x, y, dx, dy; - float e, e(1,0), e(0,1) ; // valeur d’erreur et incréments - dy = y2 - y1 ; - dx = x2 - x1 ; - y = y1 ; // rangée initiale - e = 0,0 ; // valeur d’erreur initiale - e(1,0) = dy / dx ; - e(0,1) = -1.0 ; - for (x = x1, x = x2, x++) { - sortie.s_pixel(x, y, couleur); - if ((e = e + e(1,0)) >= 0,5) { // erreur pour le pixel suivant de même rangée - y = y + 1 ; // choisir plutôt le pixel suivant dans la rangée supérieure - e = e + e(0,1) ; // ajuste l’erreur commise dans cette nouvelle rangée - } - } + // int x, y, dx, dy; + // float e, e(1, 0), e(0, 1) ; // valeur d’erreur et incréments + // dy = y2 - y1 ; + // dx = x2 - x1 ; + // y = y1 ; // rangée initiale + // e = 0, 0 ; // valeur d’erreur initiale + // e(1, 0) = dy / dx ; + // e(0, 1) = -1.0 ; + // for (x = x1; x <= x2; x++) { + // sortie.s_pixel(x, y, couleur); + // if ((e = e + e(1, 0)) >= 0, 5) { // erreur pour le pixel suivant de même rangée + // y = y + 1 ; // choisir plutôt le pixel suivant dans la rangée supérieure + // e = e + e(0, 1) ; // ajuste l’erreur commise dans cette nouvelle rangée + // } + // } + // return 0; return 1; } @@ -148,28 +259,28 @@ int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel } int cercle(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) { - sortie=entree; - for (int x=0, x=image.g_dimensionX(), x++) { - for (int y=0, y=image.g_dimensionY(), y++) { - if (sqrt(pow(x-x0, 2) + pow(y-y0, 2)) == r) { + sortie = entree; + for (int x = 0; x <= entree.g_dimensionX(); x++) { + for (int y = 0; y <= entree.g_dimensionY(); y++) { + if (sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) { sortie.s_pixel(x, y, couleur); } } } - return 1; + return 0; } -int disque(Image entree, Image &sortie, int x, int y, int r, Pixel couleur) { - - sortie=entree; - for (int x=0, x=image.g_dimensionX(), x++) { - for (int y=0, y=image.g_dimensionY(), y++) { - if (sqrt(pow(x-x0, 2) + pow(y-y0, 2)) <= r) { +int disque(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) { + + sortie = entree; + for (int x = 0; x <= entree.g_dimensionX(); x++) { + for (int y = 0; y <= entree.g_dimensionY(); y++) { + if (sqrt(pow(x - x0, 2) + pow(y - y0, 2)) <= r) { sortie.s_pixel(x, y, couleur); } } } - return 1; + return 0; } // Geométrie @@ -209,15 +320,15 @@ int retourner(Image entree, Image &sortie, int rotation) { int redimensionner(Image entree, Image &sortie, int x1, int x2, int y1, int y2) { - sortie = *new Image(x2-x1, y2-y1, entree.g_maxComposante(), entree.g_typeComposantes()); + sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(), entree.g_typeComposantes()); Pixel pixel = entree.g_pixelVide(); - for (int x = x1, x <= x2, x++) { - for (int y = y1, y <= y2, y++) { - entree.g_pixel(x+x1, y+y1, pixel); + for (int x = x1; x <= x2; x++) { + for (int y = y1; y <= y2; y++) { + entree.g_pixel(x + x1, y + y1, pixel); sortie.s_pixel(x, y, pixel); } } - return 1; + return 0; } // Modification couleur diff --git a/src/utilitaires.cpp b/src/utilitaires.cpp new file mode 100644 index 0000000..7334fbc --- /dev/null +++ b/src/utilitaires.cpp @@ -0,0 +1,82 @@ +#define NOMBREOR 1.61803398875 + +void presentation() { + cout << " ____ ___ _ ____ " << endl + << "| _ \\|_ _|| | / ___|" << endl + << "| |_) || | | | | | _ " << endl + << "| __/ | | | |___| |_| |" << endl + << "|_| |___||_____|\\____|" << endl; +} + +Image imageDefaut() { + int dimY = 256, dimX = dimY * NOMBREOR, maxComposante = 255; + Image imageRoue(dimX, dimY, maxComposante, PILG_RVB); + Pixel pointRoue = imageRoue.g_pixelVide(); + int x, y, step; + float substep, lum; + for (x = 0; x < dimX; x++) { + for (y = 0; y < dimY; y++) { + step = (x * 6.0) / dimX; + substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante; + lum = 1 - ((float) y) / dimY; + switch (step) { + case 0: + pointRoue.r = maxComposante; + pointRoue.v = substep; + pointRoue.b = 0; + break; + case 1: + pointRoue.r = maxComposante - substep; + pointRoue.v = maxComposante; + pointRoue.b = 0; + break; + case 2: + pointRoue.r = 0; + pointRoue.v = maxComposante; + pointRoue.b = substep; + break; + case 3: + pointRoue.r = 0; + pointRoue.v = maxComposante - substep; + pointRoue.b = maxComposante; + break; + case 4: + pointRoue.r = substep; + pointRoue.v = 0; + pointRoue.b = maxComposante; + break; + case 5: + pointRoue.r = maxComposante; + pointRoue.v = 0; + pointRoue.b = maxComposante - substep; + break; + default: + pointRoue.r = pointRoue.v = pointRoue.b = 0; + } + + // Dégradé vers le noir + pointRoue.r = pointRoue.r * lum; + pointRoue.v = pointRoue.v * lum; + pointRoue.b = pointRoue.b * lum; + + imageRoue.s_pixel(x, y, pointRoue); + } + } + return imageRoue; +} + +int chaineVersEntier(string chaine, int &entier) { + entier = atoi(chaine.c_str()); + if (entier == 0 && chaine != "0") { + return 1; + } + return 0; +} + +int chaineVersFlottant(string chaine, float &flottant) { + flottant = atof(chaine.c_str()); + if (flottant == 0 && chaine != "0") { + return 1; + } + return 0; +} diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..dd84e96 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Pikachu* \ No newline at end of file diff --git a/tests/PikachuP1.pbm b/tests/PikachuP1.pbm new file mode 100644 index 0000000..87871e5 Binary files /dev/null and b/tests/PikachuP1.pbm differ diff --git a/tests/PikachuP2.pgm b/tests/PikachuP2.pgm new file mode 100644 index 0000000..e0b39bf Binary files /dev/null and b/tests/PikachuP2.pgm differ diff --git a/tests/PikachuP3.ppm b/tests/PikachuP3.ppm new file mode 100644 index 0000000..b6715f0 Binary files /dev/null and b/tests/PikachuP3.ppm differ diff --git a/tests/PikachuP4.pbm b/tests/PikachuP4.pbm new file mode 100644 index 0000000..ca06c16 Binary files /dev/null and b/tests/PikachuP4.pbm differ diff --git a/tests/PikachuP5.pgm b/tests/PikachuP5.pgm new file mode 100644 index 0000000..ce9386c Binary files /dev/null and b/tests/PikachuP5.pgm differ diff --git a/tests/PikachuP6.ppm b/tests/PikachuP6.ppm new file mode 100644 index 0000000..44e3faa Binary files /dev/null and b/tests/PikachuP6.ppm differ