Fonctions trait(), retourner(), convRVB(), cercle(), disque(), redimensionner

Les fonctions sont accessibles en mode testing mais leur commande n'est pas intégrée.
* Traitement d'image
	* Ajout de la fonction trait() (algorithme original), de retourner() et de convRVB()
	* Correction des fonctions cercle(), disque() et redimensionner()
* Utilitaires
	* Ajout d'un fichier de log (PILG-log.txt), pour éviter de surcharger la console, et fonctionner même en mode RELEASE
	* Déplacement de afficherImage() depuis analyserCommande.cpp
	* Ajout d'une constante ECHELLE à afficherImage() pour zoomer l'affichage
* Objet Image
	* Correction d'une inversion X/Y visible sur des images plus hautes que large
* Mise à jour de TODO.md
* Modification des règles de formattage (encore des lignes pour rien)
This commit is contained in:
Geoffrey Frogeye 2014-05-20 20:00:32 +02:00
parent 077ef18a41
commit a618bdaf42
10 changed files with 456 additions and 203 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
*.sublime-*
PILG-log.txt

28
TODO.md
View file

@ -18,10 +18,10 @@
* Pixel **C**
* Image **C**
* Fonctions **D**
* Gestion de fichier **D**
* Gestion de fichier **A**
* Créer **C**
* Ouvrir **D**
* Enregistrer **D**
* Ouvrir **C**
* Enregistrer **C**
* Importer **A**
* Édition
* Copier tout
@ -30,24 +30,24 @@
* Annuler
* Refaire
* Couleur **D**
* Teinte **A**
* Teinte **D**
* Saturation **D**
* Luminosité **A**
* Contraste **A**
* Dessin **D**
* Trait **A**
* Luminosité **D**
* Contraste
* Dessin **C**
* Trait **C**
* Rectangle **C**
* Cercle **A**
* Disque **A**
* Cercle **C**
* Disque **C**
* Géométrie **D**
* Zoomer
* Pivoter **C**
* Retourner **D**
* Redimensionner **A**
* Conversion du mode **D**
* Retourner **C**
* Redimensionner **C**
* Conversion du mode **C**
* Binaire **C**
* Niveaux de gris **C**
* Couleur **D**
* Couleur **C**
* Aide
* Documentation

View file

@ -11,13 +11,16 @@ SDL_Surface *fenetreImage;
void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
int nbOctetsParPixel = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
switch (nbOctetsParPixel) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
@ -28,7 +31,9 @@ void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
@ -41,18 +46,14 @@ void setNomFenetre(std::string nom) { // Change le nom de la fenêtre
void pointFenetre(int x, int y, int r, int v, int b) {
// std::cout << "(" << x << ";" << y << ") = (" << r << ";" << v << ";" << b << ")" << std::endl; // DEBUG
Uint32 pixel;
Uint8 u_r, u_v, u_b, u_a;
u_r = (r > 255 ? 0xff : (Uint8) r);
u_v = (v > 255 ? 0xff : (Uint8) v);
u_b = (b > 255 ? 0xff : (Uint8) b);
u_a = 0xff;
pixel = SDL_MapRGBA(fenetreImage->format, u_r, u_v, u_b, u_a);
definirPixel(fenetreImage, x, y, pixel);
}
void afficherFenetre() {
@ -70,7 +71,8 @@ void attendreFenetre() {
do {
SDL_WaitEvent(&evenement);
} while (evenement.type != SDL_QUIT && evenement.type != SDL_KEYDOWN); //|| evenement.type != SDL_KEYDOWN);
} while (evenement.type != SDL_QUIT &&
evenement.type != SDL_KEYDOWN); //|| evenement.type != SDL_KEYDOWN);
}
void fermerFenetre() {
@ -81,12 +83,15 @@ void fermerFenetre() {
}
void ouvrirFenetre(int dimensionX, int dimensionY, std::string nom) { // Crée une fenêtre
void ouvrirFenetre(int dimensionX, int dimensionY,
std::string nom) { // Crée une fenêtre
SDL_Init(SDL_INIT_VIDEO);
fenetreDimensionX = dimensionX;
fenetreDimensionY = dimensionY;
fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32, SDL_HWSURFACE);
fenetreImage = SDL_CreateRGBSurface(SDL_HWSURFACE, fenetreDimensionX, fenetreDimensionY, 32, 0, 0, 0, 0);
fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32,
SDL_HWSURFACE);
fenetreImage = SDL_CreateRGBSurface(SDL_HWSURFACE, fenetreDimensionX,
fenetreDimensionY, 32, 0, 0, 0, 0);
SDL_FillRect(fenetreImage, NULL, SDL_MapRGB(fenetreEcran->format, 0, 0, 0));
setNomFenetre(nom);
SDL_LockSurface(fenetreImage);

View file

@ -2,45 +2,6 @@
#include <string>
#include <iostream>
void afficherImage(Image image) {
int x, y, r, v, b, dimensionX = image.g_dimensionX(), dimensionY = image.g_dimensionY(), typeComposantes = image.g_typeComposantes();
float ratio = (255.0 / image.g_maxComposante());
Pixel pixel;
if (fenetreOuverte && (dimensionX != fenetreDimensionX || dimensionY != fenetreDimensionY)) {
fermerFenetre();
}
ouvrirFenetre(dimensionX, dimensionY, "PILG");
for (x = 0; x < dimensionX; x++) {
for (y = 0; y < dimensionY; y++) {
image.g_pixel(x, y, pixel);
switch (typeComposantes) {
case PILG_BIN:
r = v = b = (pixel.n ? 255 : 0);
break;
case PILG_NIV:
r = v = b = pixel.g * ratio;
break;
case PILG_RVB:
r = pixel.r * ratio;
v = pixel.v * ratio;
b = pixel.b * ratio;
break;
}
pointFenetre(x, y, r, v, b);
}
}
afficherFenetre();
}
void messageErreur(string message) {
cerr << "Erreur : " << message << '.' << endl;
}
void decoupeCommande(string commande, vector< string > &decoupe) {
// Boucle de découpage
// vector< string > decoupe;
@ -50,13 +11,17 @@ void decoupeCommande(string commande, vector< string > &decoupe) {
bool vaEchapper = false;
bool entreSimplesGuillemets = false;
bool entreDoublesGuillemets = false;
for (int i = 0; i < commande.length(); i++) {
echape = false;
if (vaEchapper) {
vaEchapper = false;
echape = true;
}
if (commande[i] == ' ' && !(echape || entreSimplesGuillemets || entreDoublesGuillemets)) {
if (commande[i] == ' ' && !(echape || entreSimplesGuillemets ||
entreDoublesGuillemets)) {
// cout << i << " : " << "espace" << endl;
if (!dansLeVide) {
// cout << "Ajout de " << elementCourrant << endl;
@ -92,6 +57,7 @@ void decoupeCommande(string commande, vector< string > &decoupe) {
dansLeVide = false;
}
}
if (!dansLeVide) {
// cout << "Ajout de " << elementCourrant << endl;
decoupe.push_back(elementCourrant);
@ -110,7 +76,8 @@ typedef struct Commande {
vector< string > argumentsPresents;
} Commande;
int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &image) {
int analyserDecoupe(Commande &commande, vector< string > decoupe,
Image const &image) {
// for (int i = 0; i < decoupe.size(); i++) { // DEBUG
// cout << "Argument " << i << " = " << decoupe[i] << endl;
// }
@ -123,24 +90,28 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
if (decoupe[i] == "-x1" || decoupe[i] == "-x0" || decoupe[i] == "-x") {
commande.argumentsPresents.push_back("x1");
i++;
if (chaineVersEntier(decoupe[i], commande.x1)) {
return 3;
}
} else if (decoupe[i] == "-y1" || decoupe[i] == "-y0" || decoupe[i] == "-y") {
commande.argumentsPresents.push_back("y1");
i++;
if (chaineVersEntier(decoupe[i], commande.y1)) {
return 3;
}
} else if (decoupe[i] == "-x2") {
commande.argumentsPresents.push_back("x2");
i++;
if (chaineVersEntier(decoupe[i], commande.x2)) {
return 3;
}
} else if (decoupe[i] == "-y2") {
commande.argumentsPresents.push_back("y2");
i++;
if (chaineVersEntier(decoupe[i], commande.y2)) {
return 3;
}
@ -148,6 +119,7 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
commande.argumentsPresents.push_back("couleur");
i++;
commande.couleur = image.g_pixelVide();
switch (image.g_typeComposantes()) {
case PILG_BIN:
if (decoupe[i] == "b" || decoupe[i] == "1") {
@ -157,42 +129,55 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
} else {
return 4;
}
break;
case PILG_NIV:
int g;
if (!chaineVersEntier(decoupe[i], g)) {
return 3;
}
if (g > image.g_maxComposante()) {
return 5;
}
commande.couleur.g = g;
break;
case PILG_RVB:
int composante = 0;
string chaineCourante = "";
int entierCourant = 0;
for (int iS = 0; iS <= decoupe[i].length(); iS++) {
if (decoupe[i][iS] == ':' || iS == decoupe[i].length()) {
if (chaineVersEntier(chaineCourante, entierCourant)) {
return 3;
}
if (entierCourant > image.g_maxComposante()) {
return 5;
}
switch (composante) {
case 0:
commande.couleur.r = entierCourant;
break;
case 1:
commande.couleur.v = entierCourant;
break;
case 2:
commande.couleur.b = entierCourant;
break;
default:
return 6;
}
chaineCourante = "";
entierCourant = 0;
composante++;
@ -200,17 +185,21 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
chaineCourante += decoupe[i][iS];
}
}
if (composante != 3) {
return 6;
}
break;
}
if (!image.v_pixel(commande.couleur)) {
return 7;
}
} else if (decoupe[i] == "-angle" || decoupe[i] == "-a") {
commande.argumentsPresents.push_back("angle");
i++;
if (chaineVersFlottant(decoupe[i], commande.angle)) {
return 8;
}
@ -223,10 +212,14 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
}
}
// for (int i = 0; i < commande.argumentsPresents.size(); i++) { // DEBUG
// cout << "Argument présent " << i << " = " << commande.argumentsPresents[i] << endl;
// }
#if DEBUG
for (int i = 0; i < commande.argumentsPresents.size(); i++) {
journal << "\"" << commande.argumentsPresents[i] << "\" ";
}
journal << endl;
#endif
return 0;
}
@ -236,6 +229,7 @@ bool argumentPresent(Commande commande, string argumentVoulu) {
return true;
}
}
return false;
}
@ -244,7 +238,8 @@ int executerCommande(Commande commande, Image &image) {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2")
&& argumentPresent(commande, "y1") && argumentPresent(commande, "y2")
&& argumentPresent(commande, "couleur")) {
if (rectangle(image, image, commande.x1, commande.y1, commande.x2, commande.y2, commande.couleur)) {
if (rectangle(image, image, commande.x1, commande.y1, commande.x2, commande.y2,
commande.couleur)) {
return 3;
}
} else {
@ -267,58 +262,75 @@ int executerCommande(Commande commande, Image &image) {
if (convNIV(image, image)) {
return 3;
}
// } else if (commande.fonction == "convRVB") {
// convRVB(image, image);
} else {
return 1;
}
return 0;
}
void procederCommande(vector< string > decoupe, Image &image) {
Commande commande;
switch (analyserDecoupe(commande, decoupe, image)) {
case 0:
switch (executerCommande(commande, image)) {
case 0:
break;
case 1:
messageErreur("Fonction inconnue");
break;
case 2:
messageErreur("Arguments manquants");
break;
case 3:
messageErreur("Erreur dans l'execution de la commande");
break;
default:
messageErreur("Impossible d'éxecuter la fonction");
}
break;
case 1:
messageErreur("Un argument a été attendu et autre chose a été donné");
break;
case 2:
messageErreur("Argument inconnu");
break;
case 3:
messageErreur("Un entier a été attendu et n'a pas été donné");
break;
case 4:
messageErreur("La couleur d'une image binaire doit être blanc (1) ou noir (0)");
break;
case 5:
messageErreur("La valeur d'une composante de couleur donnée est superieure au maximum de composante de l'image");
break;
case 6:
messageErreur("La couleur d'une image RVB possède trois composantes");
break;
case 7:
messageErreur("La couleur donnée n'est pas valide, la raison en est inconnue");
break;
case 8:
messageErreur("Un nombre décimal a été attendu et n'a pas été donné (le programme n'accepte que les points)");
break;
default:
messageErreur("Impossible d'analyser la commande");
break;
@ -332,6 +344,7 @@ void boucleDeCommandes(Image image) { // REPL
while (continuer) {
cout << "$ ";
getline(cin, commandeTexte);
if (commandeTexte == "quitter" || commandeTexte == "exit") {
continuer = false;
} else {

View file

@ -1,12 +1,17 @@
#include "image.h"
Image::Image(int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes): m_dimensionX(dimensionX), m_dimensionY(dimensionY), m_maxComposante(maxComposante), m_typeComposantes(typeComposantes) {
Image::Image(int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes): m_dimensionX(dimensionX), m_dimensionY(dimensionY),
m_maxComposante(maxComposante), m_typeComposantes(typeComposantes) {
Pixel pixelVide = g_pixelVide();
for (int xT = 0; xT < dimensionX; xT++) {
std::vector< Pixel > colonne;
for (int yT = 0; yT < dimensionX; yT++) {
for (int yT = 0; yT < dimensionY; yT++) {
colonne.push_back(pixelVide);
}
m_tab.push_back(colonne);
}
}
@ -53,17 +58,21 @@ Pixel Image::g_pixelVide() const {
Pixel pixel;
pixel.typeComposantes = m_typeComposantes;
pixel.maxComposante = m_maxComposante;
switch (pixel.typeComposantes) {
case PILG_BIN:
pixel.b = false;
break;
case PILG_NIV:
pixel.g = 0;
break;
case PILG_RVB:
pixel.r = pixel.v = pixel.b = 0;
break;
}
return pixel;
}
@ -79,14 +88,17 @@ bool Image::v_pixel(Pixel pixel) const {
case PILG_BIN:
return true;
break;
case PILG_NIV:
return (pixel.g <= pixel.maxComposante);
break;
case PILG_RVB:
return (pixel.r <= pixel.maxComposante
&& pixel.v <= pixel.maxComposante
&& pixel.b <= pixel.maxComposante);
break;
default:
return false;
break;

View file

@ -14,7 +14,8 @@ typedef struct Pixel {
class Image {
public:
Image(int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes);
Image(int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes);
// Getters
int g_dimensionX() const;
int g_dimensionY() const;

View file

@ -11,20 +11,21 @@ using namespace std;
#define NOMBREOR 1.61803398875
int main(int argc, char *args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL
#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
#endif
presentation();
cout << endl;
Image image = imageDefaut();
if (argc > 1) { // Si la commande a été entrée avec des arguments
vector< string > decoupe;
for (int i = 1; i < argc; i++) {
decoupe.push_back(args[i]);
}
procederCommande(decoupe, image);
} else {
afficherImage(image);

View file

@ -16,43 +16,51 @@ Image genererRoue(int dimX, int dimY, int maxComposante) {
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;
}
// Dégradé vers le noir
pointRoue.r = pointRoue.r * lum;
pointRoue.v = pointRoue.v * lum;
@ -64,12 +72,17 @@ Image genererRoue(int dimX, int dimY, int maxComposante) {
// pointRoue.b = (pointRoue.b > maxComposante ? maxComposante : pointRoue.b);
if (imageRoue.s_pixel(x, y, pointRoue) == 1) {
cerr << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" << endl;
cout << "X : " << x << " - Y: " << y << " - R : " << pointRoue.r << " - V : " << pointRoue.v << " - B : " << pointRoue.b << endl; // DEBUG
journal << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" <<
endl;
journal << "X : " << x << " - Y: " << y << " - R : " << pointRoue.r << " - V : "
<<
pointRoue.v << " - B : " << pointRoue.b << endl;
}
imageRoue.g_pixel(x, y, pointRoue);
}
}
return imageRoue;
}
@ -77,12 +90,14 @@ Image genererDegrade(int dimX, int dimY, int maxComposante) {
Image image(dimX, dimY, maxComposante, PILG_NIV);
Pixel pixel = image.g_pixelVide();
int x, y;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
pixel.g = (float) x * maxComposante / dimX;
image.s_pixel(x, y, pixel);
}
}
return image;
}
@ -90,59 +105,71 @@ Image genererBruit(int dimX, int dimY) {
Image image(dimX, dimY, 0, PILG_BIN);
Pixel pixel = image.g_pixelVide();
int x, y;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
pixel.n = ((float) rand() / RAND_MAX) < ((float) x / dimX);
image.s_pixel(x, y, pixel);
}
}
return image;
}
int appliquer(Image &image, string nomFichier, string ID, bool ASCII) {
int appliquer(Image &image, string nomFichier, bool ASCII) {
ouvrir(image, "tests/" + nomFichier);
sauver(image, "tests/" + ID, ASCII, nomFichier);
Pixel pixel;
image.g_pixel(image.g_dimensionX() / 2, image.g_dimensionY() / 2, pixel);
// trait(image, image, image.g_dimensionX() / 4, image.g_dimensionY() / 4,
// image.g_dimensionX() - image.g_dimensionX() / 4,
// image.g_dimensionY() - image.g_dimensionY() / 4, pixel);
// cercle(image, image, image.g_dimensionX() / 2, image.g_dimensionY() / 2,
// image.g_dimensionY() / 4, pixel);
// disque(image, image, image.g_dimensionX() / 2, image.g_dimensionY() / 2,
// image.g_dimensionY() / 4, pixel);
// redimensionner(image, image, image.g_dimensionX() / 4, image.g_dimensionY() / 4,
// image.g_dimensionX() - image.g_dimensionX() / 4,
// image.g_dimensionY() - image.g_dimensionY() / 4);
// redimensionner(image, image, 0, 0, image.g_dimensionY(), image.g_dimensionY());
// retourner(image, image, 3);
// convBIN(image, image);
// convNIV(image, image);
// convRVB(image, image);
sauver(image, "tests/E_" + nomFichier, ASCII, nomFichier);
afficherImage(image);
attendreFenetre();
}
int main(int argc, char *args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL
#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
#endif
presentation();
#define DIMENSIONS 50
Image image1 = genererRoue(DIMENSIONS*2, DIMENSIONS, 255);
Image image2 = genererRoue(DIMENSIONS*2, DIMENSIONS, 255);
cout << "Éxecution des instructions dans testing.cpp." << endl << endl;
#define DIMENSIONS 50
Image image1 = genererRoue(DIMENSIONS * 2, DIMENSIONS, 255);
Image image2 = genererRoue(DIMENSIONS * 2, DIMENSIONS, 255);
// Image image1; // Tester si ça marche
// afficherImage(image1);
// attendreFenetre();
// // Roue
// Image image = image1.g_vide();
// for (float i = 0; i < 2 * PI; i += 0.1) {
// pivoter(image1, image, DIMENSIONS/2, DIMENSIONS/2, i);
// afficherImage(image);
// }
// Ouvrir fichier
appliquer(image1, "PikachuP1.pbm", "1", true);
appliquer(image1, "PikachuP2.pgm", "2", true);
appliquer(image1, "PikachuP3.ppm", "3", true);
appliquer(image1, "PikachuP4.pbm", "4", false);
appliquer(image1, "PikachuP5.pgm", "5", false);
appliquer(image1, "PikachuP6.ppm", "6", false);
appliquer(image1, "PikachuP1.pbm", true);
appliquer(image1, "PikachuP2.pgm", true);
appliquer(image1, "PikachuP3.ppm", true);
appliquer(image1, "PikachuP4.pbm", false);
appliquer(image1, "PikachuP5.pgm", false);
appliquer(image1, "PikachuP6.pgm", false);
// // Neige en dégradé
// for (int i; i < 300; i++) {
// afficherImage(genererBruit(200, 200));
// }
// Cycle de couleurs avec utilisation d'Image
// Image imageRoue(dimX, dimY, 255, PILG_RVB);
// Pixel pointRoueRoue = imageRoue.g_pixelVide();
@ -164,7 +191,6 @@ int main(int argc, char *args[]) {
// }
// afficherFenetre();
// }
// // Cycle de couleurs sans utilisation d'Image
// int x, y, c;
// for (c = 0; c < 256; c++) { // À peu près 75 FPS avec SDL
@ -175,10 +201,7 @@ int main(int argc, char *args[]) {
// }
// afficherFenetre();
// }
// cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl;
fermerFenetre();
return 0;
}

View file

@ -7,28 +7,27 @@
typedef enum {PILG_TYPE, PILG_DIMENSIONS, PILG_MAXCOMPOSANTE, PILG_IMAGE} PILG_OuvrirEtape;
// Gestion de fichiers
int creer(Image &sortie, int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes) { // Créer une image de dimensions X et Y
int creer(Image &sortie, int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes) { // Créer une image de dimensions X et Y
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
return 0;
}
int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à partir du nom du fichier ***Geoffrey
int ouvrir(Image &sortie,
string nomFichier) { // Ouvrir une image existante à partir du nom du fichier
// Ouverture du fichier
#if DEBUG
cout << "" << nomFichier << endl;
#endif
journal << "" << nomFichier << endl;
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());
int tailleFichier(streamFichier.tellg());
// Stockage du fichier dans une chaîne
streamFichier.seekg(0, ios::beg);
char *fichier_caracteres = new char [tailleFichier];
streamFichier.read(fichier_caracteres, tailleFichier);
streamFichier.close();
// Variables d'informations
char cara;
PILG_OuvrirEtape ouvrirEtape(PILG_TYPE);
@ -37,7 +36,6 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
int dimensionY;
int maxComposante;
PILG_Comp typeComposantes;
// Variables de traitement du fichier
string element("");
int x(0);
@ -49,9 +47,11 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
for (int c(0); c < tailleFichier; c++) {
cara = fichier_caracteres[c];
if (ouvrirEtape != PILG_IMAGE) {
if (cara == FICHIER_SEPARATEUR) { // En cas de nouvel élément
if (element[0] != '#') { // Si c'est un commentaire, on passe à l'élément suivant
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') {
@ -60,29 +60,35 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
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;
@ -92,15 +98,17 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
}
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
journal << "Type de fichier : " << element << " (" << ((
typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ?
"Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" :
"Brut") << ")" << endl;
break;
case PILG_DIMENSIONS: {
bool espaceDepasse(false);
string dimensionXchaine("");
string dimensionYchaine("");
for (int j(0); j < element.size(); j++) {
if (element[j] == ' ') {
espaceDepasse = true;
@ -110,14 +118,17 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
dimensionXchaine += 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
journal << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" <<
endl;
if (typeComposantes == PILG_BIN) {
ouvrirEtape = PILG_IMAGE;
} else {
@ -125,11 +136,12 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
}
}
break;
case PILG_MAXCOMPOSANTE:
chaineVersEntier(element, maxComposante);
#if DEBUG
cout << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") << " : " << maxComposante << endl;
#endif
journal << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") <<
" : "
<< maxComposante << endl;
ouvrirEtape = PILG_IMAGE;
break;
@ -137,11 +149,13 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
return 4;
break;
}
if (ouvrirEtape == PILG_IMAGE) {
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
pixel = sortie.g_pixelVide();
}
}
element = "";
} else {
element += cara;
@ -162,10 +176,12 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
chaineVersEntier(tmpASCII, pixel.r);
RVBcomposante = 1;
break;
case 1:
chaineVersEntier(tmpASCII, pixel.v);
RVBcomposante = 2;
break;
case 2:
chaineVersEntier(tmpASCII, pixel.b);
RVBcomposante = 0;
@ -178,11 +194,11 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
sortie.s_pixel(x, y, pixel);
x++;
}
tmpASCII = "";
} else {
tmpASCII += cara;
}
}
} else {
if (typeComposantes == PILG_BIN) {
@ -190,6 +206,7 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
pixel.n = !((cara >> i) & 0x01);
sortie.s_pixel(x, y, pixel);
x++;
if (x >= dimensionX) {
y++;
x = 0;
@ -202,10 +219,12 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
pixel.r = caraVersEntier(cara);
RVBcomposante = 1;
break;
case 1:
pixel.v = caraVersEntier(cara);
RVBcomposante = 2;
break;
case 2:
pixel.b = caraVersEntier(cara);
RVBcomposante = 0;
@ -220,6 +239,7 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
}
}
}
if (x >= dimensionX) {
y++;
x += -dimensionX;
@ -229,45 +249,54 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
} else {
return 1;
}
#if DEBUG
cout << endl;
#endif
journal << endl;
return 0;
}
int sauver(Image entree, string nomFichier, bool ASCII, string commentaire) { // Sauvegarder l'image obtenue dans un nouveau fichier
int sauver(Image entree, string nomFichier, bool ASCII,
string commentaire) { // Sauvegarder l'image obtenue dans un nouveau fichier
ofstream fichier(nomFichier.c_str(), ios::out | ios::trunc);
char numero;
switch (entree.g_typeComposantes()) {
case PILG_BIN:
numero = ASCII ? '1' : '4';
break;
case PILG_NIV:
numero = ASCII ? '2' : '5';
break;
case PILG_RVB:
numero = ASCII ? '3' : '6';
break;
default:
return 1;
}
fichier << "P" << numero << FICHIER_SEPARATEUR;
if (commentaire != "") {
fichier << "# " << commentaire << FICHIER_SEPARATEUR;
}
fichier << entree.g_dimensionX() << " " << entree.g_dimensionY() << 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;
char brutBINpixel;
int brutBINpixelRang = 7;
for (int y = 0; y < entree.g_dimensionY(); y++) {
for (int x = 0; x < entree.g_dimensionX(); x++) {
entree.g_pixel(x, y, pixel);
switch (entree.g_typeComposantes()) {
case PILG_BIN:
if (ASCII) {
@ -282,34 +311,45 @@ int sauver(Image entree, string nomFichier, bool ASCII, string commentaire) { //
} else {
brutBINpixel |= 1 << brutBINpixelRang;
}
brutBINpixelRang--;
if (brutBINpixelRang < 0) {
fichier << brutBINpixel;
brutBINpixelRang = 7;
}
}
break;
case PILG_NIV:
if (ASCII) {
fichier << pixel.g << FICHIER_SEPARATEUR;
} else {
fichier << (char) pixel.g;
}
break;
case PILG_RVB:
if (ASCII) {
fichier << pixel.r << FICHIER_SEPARATEUR << pixel.v << FICHIER_SEPARATEUR << pixel.b << FICHIER_SEPARATEUR;
fichier << pixel.r << FICHIER_SEPARATEUR
<< pixel.v << FICHIER_SEPARATEUR
<< pixel.b << FICHIER_SEPARATEUR;
} else {
fichier << (char) pixel.r
<< (char) pixel.v
<< (char) pixel.b;
}
break;
default:
return 1;
}
}
}
fichier.close();
return 0;
}
@ -323,63 +363,60 @@ int importer(Image entree, Image &sortie, string nomFichier, int x, int y) {
// sortie.s_pixel(x1 + x, y1 + y, fichierImporte.g_pixel(x1, x2));
// FinPour
// FinPour
return 1;
}
// Couleur
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++) {
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;
}
int saturation(Image entree, Image &sortie, float saturation) { // Sature l'image
int saturation(Image entree, Image &sortie,
float saturation) { // Sature l'image
// Utilisation de la méthode TSL
return 1;
}
int luminosite(Image entree, Image &sortie, float luminosite) { // Augmente la luminosité de l'image
int luminosite(Image entree, Image &sortie,
float luminosite) { // Augmente la luminosité de l'image
// Utilisation de la méthode TSL
return 1;
}
int contraste(Image entree, Image &sortie, float contraste) { // Accentue les contrastes de l'image
int contraste(Image entree, Image &sortie,
float contraste) { // Accentue les contrastes de l'image
// À 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 derreur et incréments
// dy = y2 - y1 ;
// dx = x2 - x1 ;
// y = y1 ; // rangée initiale
// e = 0, 0 ; // valeur derreur 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 lerreur commise dans cette nouvelle rangée
// }
// }
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;
sortie = entree;
// return 0;
return 1;
for (x = 0; x <= x2 - x1; x++) {
// cout << "(" << x << ";__) a=" << ((float) x / (x2 - x1)) << " yD=" <<
// (y2 - y1) * ((float)x / (x2 - x1)) << endl;
sortie.s_pixel(x1 + x, y1 + (y2 - y1) * ((float) x / (x2 - x1)), couleur);
}
return 0;
}
int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel couleur) {
int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2,
Pixel couleur) {
sortie = entree;
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
sortie.s_pixel(x, y, couleur);
@ -391,32 +428,34 @@ 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 <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
if (sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) {
if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) {
sortie.s_pixel(x, y, couleur);
}
}
}
return 0;
}
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) {
if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) <= r) {
sortie.s_pixel(x, y, couleur);
}
}
}
return 0;
}
// Geométrie
int zoom(Image entree, Image &sortie) {
return 1;
}
@ -424,6 +463,7 @@ int pivoter(Image entree, Image &sortie, int x0, int y0, float angle) {
sortie = entree.g_vide();
float xF, yF, angleF, xI, yI, angleI, h;
Pixel pixel = entree.g_pixelVide();
for (xF = 0; xF < entree.g_dimensionX(); xF++) {
for (yF = 0; yF < entree.g_dimensionY(); yF++) {
if (xF == x0 && yF == y0) {
@ -437,28 +477,72 @@ int pivoter(Image entree, Image &sortie, int x0, int y0, float angle) {
xI = cos(angleI) * h + x0;
yI = sin(angleI) * h + y0;
}
entree.g_pixel((int) xI, (int) yI, pixel);
sortie.s_pixel((int) xF, (int) yF, pixel);
}
}
return 0;
}
int retourner(Image entree, Image &sortie, int rotation) {
rotation = rotation % 4;
int x, y;
Pixel pixel;
if (rotation == 0) {
sortie = entree;
} else {
if (rotation == 2) {
sortie = entree.g_vide();
} else {
sortie = *new Image(entree.g_dimensionY(), entree.g_dimensionX(),
entree.g_maxComposante(), entree.g_typeComposantes());
}
for (x = 0; x < entree.g_dimensionX(); x++) {
for (y = 0; y < entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixel);
switch (rotation) {
case 1:
sortie.s_pixel(entree.g_dimensionY() - y - 1, x, pixel);
break;
case 2:
journal << "5";
sortie.s_pixel(entree.g_dimensionX() - x - 1, entree.g_dimensionY() - y - 1,
pixel);
break;
case 3:
sortie.s_pixel(y, entree.g_dimensionX() - x - 1, pixel);
break;
default:
journal << "6";
return 1;
}
}
}
}
return 0;
}
int retourner(Image entree, Image &sortie, int rotation) {
int redimensionner(Image entree, Image &sortie, int x1, int y1, int x2,
int y2) {
sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(),
entree.g_typeComposantes());
Pixel pixel;
return 1;
}
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());
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 = 0; x <= x2 - x1; x++) {
for (int y = 0; y <= y2 - y1; y++) {
entree.g_pixel(x1 + x, y1 + y, pixel);
sortie.s_pixel(x, y, pixel);
}
}
return 0;
}
@ -470,23 +554,30 @@ int convBIN(Image entree, Image &sortie) {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), 0, PILG_BIN);
Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) {
case PILG_NIV:
pixelF.n = (pixelI.g > entree.g_maxComposante() / 2);
pixelF.n = (pixelI.g > (entree.g_maxComposante() / 2));
break;
case PILG_RVB:
pixelF.n = ((pixelI.r + pixelI.v + pixelI.b) / 3 > entree.g_maxComposante() / 2);
pixelF.n = ((pixelI.r + pixelI.v + pixelI.b) / 3 > (entree.g_maxComposante() /
2));
break;
default:
return 2;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
}
@ -494,35 +585,74 @@ int convNIV(Image entree, Image &sortie) {
if (entree.g_typeComposantes() == PILG_NIV) {
sortie = entree;
} else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), MAXCOMPOSANTEDEFAUT, PILG_NIV);
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(),
MAXCOMPOSANTEDEFAUT, PILG_NIV);
Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) {
case PILG_BIN:
pixelF.g = (pixelI.n ? sortie.g_maxComposante() : 0);
break;
case PILG_RVB:
pixelF.g = (pixelI.r + pixelI.v + pixelI.b) / 3.0 / entree.g_maxComposante() * sortie.g_maxComposante();
pixelF.g = (pixelI.r + pixelI.v + pixelI.b) / 3.0 / entree.g_maxComposante() *
sortie.g_maxComposante();
break;
default:
return 1;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
}
int convRVB(Image entree, Image &sortie) {
if (entree.g_typeComposantes() == PILG_RVB) {
sortie = entree;
} else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(),
MAXCOMPOSANTEDEFAUT, PILG_RVB);
Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) {
case PILG_BIN:
pixelF.r = pixelF.v = pixelF.b = (pixelI.n ? sortie.g_maxComposante() : 0);
break;
case PILG_NIV:
pixelF.r = pixelF.v = pixelF.b = (float) pixelI.g / entree.g_maxComposante() *
sortie.g_maxComposante();
break;
default:
return 1;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
}
//Help
// Aide
int aide() {
//Afficher le texte suivant :
// Afficher le texte suivant :
return 1;
}

View file

@ -1,14 +1,16 @@
#include <math.h>
#include <fstream>
#define NOMBREOR 1.61803398875
ofstream journal("PILG-log.txt", ios::out | ios::trunc);
void presentation() {
cout << " ____ ___ _ ____ " << endl
<< "| _ \\|_ _|| | / ___|" << endl
<< "| |_) || | | | | | _ " << endl
<< "| __/ | | | |___| |_| |" << endl
<< "|_| |___||_____|\\____|" << endl
<< endl;
<< "|_| |___||_____|\\____|" << endl;
}
Image imageDefaut() {
@ -17,42 +19,50 @@ Image imageDefaut() {
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;
}
@ -61,26 +71,81 @@ Image imageDefaut() {
pointRoue.r = pointRoue.r * lum;
pointRoue.v = pointRoue.v * lum;
pointRoue.b = pointRoue.b * lum;
imageRoue.s_pixel(x, y, pointRoue);
}
}
return imageRoue;
}
void afficherImage(Image image) {
#define ECHELLE 1
int x, y, r, v, b, eX, eY, dimensionX = image.g_dimensionX() * ECHELLE,
dimensionY = image.g_dimensionY() * ECHELLE,
typeComposantes = image.g_typeComposantes();
float ratio = (255.0 / image.g_maxComposante());
Pixel pixel;
if (fenetreOuverte && (dimensionX != fenetreDimensionX ||
dimensionY != fenetreDimensionY)) {
fermerFenetre();
}
ouvrirFenetre(dimensionX, dimensionY, "PILG");
for (x = 0; x < image.g_dimensionX(); x++) {
for (y = 0; y < image.g_dimensionY(); y++) {
image.g_pixel(x, y, pixel);
switch (typeComposantes) {
case PILG_BIN:
r = v = b = (pixel.n ? 255 : 0);
break;
case PILG_NIV:
r = v = b = pixel.g * ratio;
break;
case PILG_RVB:
r = pixel.r * ratio;
v = pixel.v * ratio;
b = pixel.b * ratio;
break;
}
for (eX = 0; eX < ECHELLE; eX++) {
for (eY = 0; eY < ECHELLE; eY++) {
pointFenetre(x * ECHELLE + eX, y * ECHELLE + eY, r, v, b);
}
}
}
}
afficherFenetre();
}
void messageErreur(string message) {
cerr << "Erreur : " << message << '.' << endl;
journal << "Erreur : " << message << '.' << endl;
}
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;
}
@ -88,8 +153,10 @@ int caraVersEntier(char cara) {
// int entier = (int) (0 << 8) + cara;
// entier = entier > 0 ? entier : 256+entier;
int i, entier = 0;
for (i = 0; i < 8; i++) {
entier += ((cara >> i) & 0x01) ? pow(2, i) : 0;
}
return entier;
}