[C++] Vérification programme image .pgm

Statut
N'est pas ouverte pour d'autres réponses.

_Musca

Touriste
Bonjour à tous,

Dans le cadre d'un cours d'informatique à l'ULB, on doit faire un petit programme en c++, les profs nous demandent de pouvoir charger une image .pgm, de pouvoir la sauvergarder, de faire son négatif, de la découper, et d'augmenter ou diminuer la luminosité.

Donc voilà j'ai fais mon programme, il fonctionne tout à fait bien, mais je sais pas si je l'ai fais de la meilleure façon.

Donc si vous pouviez jeter un petit coup d'oeil pour voir ce que je pourrais changer afin de l'améliorer

Merci beaucoup



#include <iostream>
#include <fstream>
#include <string>

using namespace std;

//initialisation des différentes fonctions

string ident;
int largeur, hauteur, pixel_maxi, i, j, tab[600][600];

//ident = Variable de début des fichiers pgm ou ppm
//largeur = largeur de la matrice du fichier pgm
//hauteur = hauteur de la matrice du fichier pgm
// pixel_maxi = chuiffre maximum qu'un pixel peut avoir
//i = ligne de la matrice
//j = colone de la matrice
//tab = tableau dans lequel on va placer les chiffres des pixels


//fonction lecture
void lecture(){
string nom_image; //variable du nom de l'image

cout << "Entrez le nom de l'image" << endl;
cin >> nom_image;
ifstream fin (nom_image.c_str());
fin >> ident;
fin >> largeur >> hauteur;
fin >> pixel_maxi;
for (i = 0; i<hauteur ;i++){
for (j = 0; j<largeur; j++){
fin >> tab[j];
}
}
cout<<"Image chargee"<<endl;
}


// fonction ecrire
void ecrire(){
string image_sauvegardee;

cout << "Entrez le nom du fichier de sauvegarde" << endl;
cin >> image_sauvegardee;
ofstream fout (image_sauvegardee.c_str());
fout << ident << endl;
fout << largeur << " " << hauteur << endl;
fout << pixel_maxi << endl;
for (i=0 ; i<hauteur ; i++){
for (j=0 ; j<largeur ; j++){
fout << tab[j] << " ";
}
fout<<endl;
}
}

//fonction luminosité
void luminosite(){
int degre;
cout<<"Introduisez la valeur de votre changement de luminosite " << endl;
cout<<"(Introduisez un nombre negatif si vous voulez noircir.)" << endl;

cin>> degre;

for (i=0 ; i<hauteur ; i++){ //avec ces deux boucles for on va pouvoir rajouter ou enlever un certain nombre à tous les pixels
for (j=0 ; j<largeur ; j++){
tab[j]=tab[j] + degre;


if (tab[j]<0){
tab[j]=0;
}
else if (tab[j]>255)
tab[j]=255;
}
}
}

//fonction decoupe
void decoupe(){

int x,y;
// x = position en x à partir de laquelle la matrice sera découpée
//y = position en y à partir de laquelle la matrice sera découpée

cout<<"Le processus de decoupage se fait ainsi :"<<endl;
cout<<"1) Vous choisissez le point sur la matrice a partir duquel aura lieu la decoupe (x et y)"<<endl;
cout<<"2) Vous indiquez la largeur en valeur absolue qu'aura votre matrice (de gauche a droite a partir du point choisit plus haut)."<<endl;
cout<<"3) Vous indiquez la hauteur en valeur absolue qu'aura votre matrice (de haut en bas a partir du point choisit plus haut)."<<endl<<endl;
cout<<"Introduisez l'endroit où commencer la découpe (x,y)"<<endl;
cin >> x >> y;
cout<<"Introduisez la largeur et la hauteur de la nouvelle image"<<endl;
cin >> largeur >> hauteur;
for (i=y ; i<(y+hauteur) ; i++){
for (j=x ; j<(x+hauteur) ;j++){
tab[i-y][j-x]=tab[j];
}
}
cout<<"Image decoupee!"<<endl;
}

//fonction negatif
void negatif(){

for (i=0 ; i<hauteur ; i++){
for (j=0 ; j<largeur ; j++){
tab[j] = (255)-(tab[j]);
}
}
cout << "Negatif produit" << endl;
}

//fonction quitter
void quitter() {

cout << "Au revoir" << endl;
}



//fonction principale
int main (int argc, char * const argv []) {



int numero;
// numero = le chiffre entré par l'utilisateur en fonction de son choix dans le menu


do {

cout << "\t \t Menu" << endl;
cout << endl;
cout << "0) Charger une image" << endl;
cout << "1) Sauvegarder une image" << endl;
cout << "2) Changer la luminosite" << endl;
cout << "3) Decouper l'image" << endl;
cout << "4) Produire le negatif" << endl;
cout << "5) Quitter" << endl;
cout <<endl;
cout << " Choisissez votre numero" << endl;
cout << endl;


cin >> numero;


switch (numero){

case 0: lecture (); cout << endl; break; // on fait appel à la fonction lecture
case 1: ecrire(); cout<< endl; break; // on fait appel à la fonction ecrire
case 2: luminosite(); cout << endl; break; // on fait appel à la fonction luminosite
case 3: decoupe(); cout << endl; break; // on fait appel à la fonction decoupe
case 4: negatif(); cout << endl; break; // on fait appel à la fonction negatif
case 5: quitter(); cout << endl; break; // on fait appel à la fonction quitter

}
if (numero>5 || numero<0){
cout << "vous avez tappe un mauvais chiffre" <<endl;
cout << endl;
}
} while (numero != 5);


system("pause");
return 0;
}
 

tqz_

Elite
A première vue j'aurai également procédé de la même façon avec les boucles pour hauteur et largeur. Le C++ ne te permet pas d'être "plus direct".
 

null

ose();
Personnellement je n'aurais pas réalisé le programme de cette manière. Le C++ est orienté objet mais toi tu l'utilises comme du C (enfin presque : cin, cout ;)).

A ta place, j'aurais déjà découpé le programme en deux classes : "vue" et "moteur" et donc d'avoir des beaux .h et .cpp. Je te montre un exemple fait y a quelques mois maintenant d'une classe qui permet de lire les fichiers .bmp : http://pastie.org/332295

Ca me semble clair qu'une découpe correcte du programme et de l'utilisation de l'OO te permettra de simplifier la lecture de ton programme et t'évitera de nombreux bugs (même si dans ton cas cela reste un petit programme, il vaut mieux prendre de bonnes habitudes).

Tu es en quelle année à l'ULB ? Tu es en informatique ou rien à voir ? (J'ai mon stage à l'ULB cette année :p)
 

Tifox

ou pas
Personnellement je n'aurais pas réalisé le programme de cette manière. Le C++ est orienté objet mais toi tu l'utilises comme du C (enfin presque : cin, cout ;)).

A ta place, j'aurais déjà découpé le programme en deux classes : "vue" et "moteur" et donc d'avoir des beaux .h et .cpp. Je te montre un exemple fait y a quelques mois maintenant d'une classe qui permet de lire les fichiers .bmp : http://pastie.org/332295

Ca me semble clair qu'une découpe correcte du programme et de l'utilisation de l'OO te permettra de simplifier la lecture de ton programme et t'évitera de nombreux bugs (même si dans ton cas cela reste un petit programme, il vaut mieux prendre de bonnes habitudes).

Tu es en quelle année à l'ULB ? Tu es en informatique ou rien à voir ? (J'ai mon stage à l'ULB cette année :p)
Je suis un peu du même avis.

J'ajouterai que si tu as un processeur récent (dual core, hyper threading), tu peux faire du multi-process ou multi-threading pour augmenter la vitesse de traitement (mais ça devient plus complexe a programmer.
 
1er
OP
_Musca

_Musca

Touriste
Je répond tantôt je pars à l'instant

Et non je suis pas en informatique mais en BA2 bioingénieur, mais on a cours d'informatique (en gros on voit les bases du c++)
 

gogoprog

Oprahiste vaudou
Comme déjà signalé, tu pourrais l'orienter objet
 
comment useless : lol la fonction quitter :p pourquoi pas utilsier seulement break; dans le case5 ? :p
 
1er
OP
_Musca

_Musca

Touriste
Comme dis plus haut je ne suis pas en informatique donc je ne saisis pas trop ce que je dois faire quand vous parlez de "orienter objet"

et pour la fonction quitter, ouais je sais, bha je trouvais ça mieux :D

en tout cas merci à tous d'avoir jeté un coup d'oeil :)
 

BiBiO

Elite
Non il ne faut pas spécialement l'orienté objet.
En fait le cours de première de programmation est un cours où tu vois les bases du c++. Ce n'est qu'en 2ème INFO que tu verras vraiment l'orienté-objet.
Les assistants n'aiment pas trop les "break" ^^.
Sinon on avait presque le même prog à faire l'année passée et c'est aussi de cette facon que j'ai procédé :).
Bonne chance pr le projet 6 :D
 
C'est écrit en procédural... L'orienté objet c'est "mieux" ;)

Les cin / cout sont les entrées sorties; elles représentent les "interfaces graphiques" version "console". => une classe View (Vue) en quelque sorte

Une classe Image représenterait ton "modèle"

Et la partie traitement; hé bien, conceptuellement tu pourrais la mettre dans une classe qui jouerait le rôle de contrôleur (le lien entre l'aspect graphique et l'aspect modèle)

=> .h prototypes de tes méthodes
=> .cpp pour les implémentations

C'est toujours mieux de coder en utilisant des libellés en anglais : ils résument beaucoup de phrase en peu de mots

Ne jamais utiliser de variables globales mais des membres privés dans tes classes.
C'est toujours bien de découper chaque déclaration de variable, attribut, membre plutôt que de les énumérer tous d'un coup car ils ont le même type. (Comme ça, tu peux mettre ton commentaire juste à côté ou au-dessus, c'est un choix personnel)

Quand tu joues avec des tableaux, c'est bien aussi de valider tes indices (min 0 max length-1)

Indenter le code le rendra plus lisible.

Les bases du C++ ce n'est pas le C. Le C++ est un langage OO dont la syntaxe utilisée vient du C; cela facilite l'aprentissage des aspects OO sans perdre du temps à se farcir une liste de mots réservés, de symboles et autres librairies.

Bases OO:
Classe, Object (instance de classe), messages (méthodes), encapsulation (attributs et méthodes au sein d'une même structure), protection des attributs (membres privés, protégés, publics), l'héritage (simple, multiple), les surcharges, les surdéfinitions, le polymorphisme...

A côté de ça, tu auras de nombreux design patterns qui ne sont que des implémentations spécifiques pour répondre à des besoins spécifiques (c'est de la réutilisation au sens large et une facilité à maintenir et à faire évoluer son code).

Evidemment, ça ne s'arrête pas là; il y a beaucoup trop de points à développer que pour les résumer en quelques lignes (l'abstraction, les collections, le transtipage, cast, les "templates", etc etc.)
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut