1

Bonjour en effet je veut juste ouvrir puis sauvegarder ( sans aucune perte sous le méme format PPM ) des image mais j'ai un soucis pour lequel je ne trouve pas de solution . l'ouverture s'arrete toujours au même endroit .

exemple de fichier :
P3
# CREATOR: The GIMP's PNM Filter Version 1.0
300 225
255
65
58
56 ....

l'ouverure se fait ainsi :
/*--recuperation de l'entete--*/
fgets(temp1,100,fic);
fgets(temps2,100,fic);
fscanf(fic,"%d %d",&ta1,&ta2); // valeurs width , length
fscanf(fic,"%d\n",&ta3); // MAX
/*--chargement dans la matrice--*/
unsigned char varb,varv,varr;

for(i=0;i<length;i++) for(j=0;j<width;j++)
{
fread(&varr,1,1,fic);
fread(&varv,1,1,fic);
fread(&varb,1,1,fic);

matR[i][j]=varr;
matV[i][j]=varv;
matB[i][j]=varb; }



partie sauvegarde :

/*--sauvegarde de l'entete--*/
fprintf(fic,"P3");
fprintf(fic,"\n# IMG ");
fprintf(fic,"%d %d",length,width);
fprintf(fic,"\n255\n");

/*--enregistrement--*/
for(i=0;i<length;i++)
for(j=0;j<width;j++)
{
fprintf(fic,"%c",(char)matR[i][j]);
fprintf(fic,"%c",(char)matV[i][j]);
fprintf(fic,"%c",(char)matB[i][j]);
}


Le resultat et que j'ai juste une partie de l'image qui s'affiche et en l'ouvrant avec GIMP j'ai un message : FIN DE FICHIER PREMATURE
effectivement en comparant les deux fichier ( original et copie ) sur la copie 2 tiers voir plus d'informations manque .

merci de m'aider si vous voyez des solutions . couic couic rotfl

2

parce que fread lit des OCTETS dans un fichier binaire.

Apparemment t'as un fichier PPM ASCII, tu dois le lire avec "fscanf"

voici ma version
/**
 * lit une image depuis un fichier PNM
 * @param name le nom de fichier à lire
 * @param dest la structure image de destination
 * @return 0 si ok, sinon un code d'erreur
 */
int lireImagePnm(char *name, image_t *dest)
{
	FILE *f;
	int magic;
	int clamp;
	int row,col;
	int width,height;
	int val;
	char buf[80];
	f=fopen(name,"rb");
	if(!f) return -EFILE;

	fscanf(f,"%s",buf);
	if(buf[0]!='P') {
		fclose(f);
		return -EFORMAT;
	}

	magic=buf[1]-'0';
	printf("pixmap-magic=%d\n",magic);

	if(magic>3) {
		printf("binary files not supported yet\n");
		return -EFORMAT;
	}

	fscanf(f,"%d %d",&width, &height);
	dest->largeur=width;
	dest->hauteur=height;

	printf("size: %dx%d\n",width,height);

	if(magic==2 || magic == 3) {
		fscanf(f,"%d",&clamp);
		printf("clamp=%d\n",clamp);
	}

	/*ajout pour le tp2: si l'image est deja allouee, on l'efface avant*/
	if(dest->pixelTab) free(dest->pixelTab);
	dest->pixelTab=(pixel_t*)malloc(sizeof(pixel_t)*width*height);
	if(!dest->pixelTab) {
		fclose(f);
		return -EMEM;
	}

	for(row=0;row<height;row++) {
		for(col=0;col<width; col++) {
			switch(magic) {
				case 1:
					fscanf(f,"%d",&val);
					dest->pixelTab[row*width+col].r=val*255;
					dest->pixelTab[row*width+col].g=val*255;
					dest->pixelTab[row*width+col].b=val*255;
				case 2:
					fscanf(f,"%d",&val);
					dest->pixelTab[row*width+col].r=(int)((float)val/(float)clamp*255.0);
					dest->pixelTab[row*width+col].g=(int)((float)val/(float)clamp*255.0);
					dest->pixelTab[row*width+col].b=(int)((float)val/(float)clamp*255.0);
					break;
				case 3:
					fscanf(f,"%d",&val);
					dest->pixelTab[row*width+col].r=(int)((float)val/(float)clamp*255.0);
					fscanf(f,"%d",&val);
					dest->pixelTab[row*width+col].g=(int)((float)val/(float)clamp*255.0);
					fscanf(f,"%d",&val);
					dest->pixelTab[row*width+col].b=(int)((float)val/(float)clamp*255.0);
					break;
			}
		}
	}
	fclose(f);
	return EOK;
}


typedef short int pixel_elem ;

typedef struct _pixel {
	pixel_elem r;
	pixel_elem g;
	pixel_elem b;
} pixel_t;

typedef struct _image {
	int hauteur;
	int largeur;
	int type;
	pixel_t *pixelTab;
} image_t;


#define EOK	0
#define EFILE	1
#define EFORMAT	2
#define EMEM	3
#define EPARM	4

3

onlymed, ton fichier ne serait-il pas coupé juste avant un caractère 0x1A ?
Si c'est le cas, il faut t'assurer que tu ouvres bien ton fichier pour une lecture en binaire.
avatar

4

Merci pour cette reponse effectivement c'était un probleme de fscanf smile le probleme est resoulu il suffisé que je mette des fscanf et je change la valeur de retour et tout marche une autre question par contre :
maintenant je voudrais appliquer des filtre a cet image en effet comme ( je connais rien en imagerie c'est pas mon domaine ) apres quelque etudes j'ai compris qu'il fallait faire une multiplication de matrices par une matrice 3*3 de transformation
hors comme en PPM chaque pixels est caracterisé par 3 valeur R V B la question est la suivante : faut il multiplier mes 3 matrices matriceR , matriceV , matriceB par cette matrice independament ? ( parsque le resultat n'a rien avoir avec ce qu'il est supposé etre )
merci pour l'aide smile

5

non, les coefs de la matrice s'appliquent à chaque composante. Imagine que matriceR=matriceV=matriceB=matrice.

6

les coefs de la matrice s'appliquent à chaque composante ?? désolé mais j'ai pas trop compris l'idée : mes trois matrice qui encode l'image sont matriceR matriceV matriceB puis une matrice matcoef de transformation . c'est quoi l'opération a calculer . pour avoir la nouvelle image avec le filtre appliquer .
merci de m'eclaircir .

7

En effet j'ai compris comment y faire le seul probleme maintenant c'est que je veut faire ce traitement en THREAD et la le grand bug puisqu'ils etulisent chacun une partie de limage le probleme c'est pour les parties ou il y'a la coupe . on ne peut toujours pas traiter les bord de limage puiqu'on a pas tout les pixels qui l'entour . avez vous des idées .?

8

en général on met des zéros pour les pixels en dehors de l'image smile

9

Bonjour ,
merci de votre reponse mais la j'ai un autre soucis en effet j'ai jamais fait du traitement d'image ( c'est plutot de la programmation parallele ce que j'essaie de faire UPC )

la ma question est sur l'application du filtre sachant que j'ai entourer l'image pas un pixel 0

00000
0xxx0
0xxx0
00000

puis j'essaie d'appliquer le filtre

0-10
-15-1
0-10
alors je procede comme suite :
void appliquerFiltre(char* name)
{
MatriceImgROut=fmatrix_allocate_2d(length,width);
MatriceImgVOut=fmatrix_allocate_2d(length,width);
MatriceImgBOut=fmatrix_allocate_2d(length,width);
coefficients=fmatrix_allocate_2d(3,3);



int h , w , i , j ;


// matrice de trasformation
coefficients[0][0] = 0 ;
coefficients[0][1] = -1;
coefficients[0][2] = 0 ;
coefficients[1][0] = -1;
coefficients[1][1] = 5;
coefficients[1][2] = -1 ;
coefficients[2][0] = 0 ;
coefficients[2][1] = -1 ;
coefficients[2][2] = 0 ;

for (h = 0 ; h < length ; h++)
for (w = 0 ; w < width ; w++)
{

/*
MatriceImgROut[h][w] = 0 ;
MatriceImgVOut[h][w] = 0 ;
MatriceImgBOut[h][w] = 0 ;*/

for (i = 0 ; i < 3 ; i++)
for (j = 0 ; j < 3 ; j++)
{
MatriceImgROut[h][w] += coefficients[i][j] * MatriceImgR[h+i][w+j] ;
MatriceImgVOut[h][w] += coefficients[i][j] * MatriceImgV[h+i][w+j] ;
MatriceImgBOut[h][w] += coefficients[i][j] * MatriceImgB[h+i][w+j] ;
}

if(MatriceImgROut[h][w]<0)
MatriceImgROut[h][w]=0;
else
if(MatriceImgROut[h][w]>255)
MatriceImgROut[h][w]=255;

if(MatriceImgVOut[h][w]<0)
MatriceImgVOut[h][w]=0;
else
if(MatriceImgVOut[h][w]>255)
MatriceImgVOut[h][w]=255;

if(MatriceImgBOut[h][w]<0)
MatriceImgBOut[h][w]=0;
else
if(MatriceImgBOut[h][w]>255)
MatriceImgBOut[h][w]=255;

}


puis j'affiche la nouvelle image est la j'ai un resultat different de ce que j'attend
sachant que si j'ouvre et je sauvegarde sans modification l'image reste la méme donc c'est plutot au moment de l'application du filtre que j'ai un probleme

voici les deux image et les resultat :


HW4d
OP29


puis méme on dirai que l'image OUT est coupé en 4-5 parties .

merci si vous voyer un probleme quelque part.

10

je crois pas qu'il y ait de problème, ça a juste une tête bizarre parce qu'il y a de la saturation... essaye avec MatriceImgXOut[h][w] = 128 + (MatriceImgXOut[h][w]-128)/2 avant le clipping ^^
(sinon utilise [ pre ] et pas [ cite ] pour le code, sinon y a des bouts qui disparaissent)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

11

avalt le clipping ?? avant l'affichage ? MatriceImgXOut[h][w] = 128 + (MatriceImgXOut[h][w]-128)/2 ou avant l'operation de calcule des pixels ?

euh j'ai essaié les deux sur la premiere bien moin de luminosité sur la deuxieme rien na changer . mais bon c'est juste un debut je voulait juste savoir si c'etait correct afin que je commence ma parallelisation ( le but ) en UPC .

K06b

mais bon j'en suis pas sur vu que avec d'autre filtre le resultat et encore loin loin du resultat . de plus je sais pas si vous le voyez sur l'image mais il y'a des trait vertical on dirai des coupure .
merci

12

ah oui en effet on voit bcp mieux qu'il y a un problème : le bloc noir en bas à droite apparaît en fantôme en blanc à certains endroits... est-ce que c'est pas un problème de dimensions de l'image ? par exemple est-ce que MatriceImgXOut[h][w] = MatriceImgX[h/2][w/2] donne bien le résultat qu'on attend ?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

13

Le coin Noir en bas a droite c'est normal y est dans l'image original . la taille me parait juste vu que si j'ouvre l'image est je la sauvegarde sans aucune modification aucun changement sur cette derniere donc ??

MatriceImgROut[h][w] = MatriceImgR[h/2][w/2] ?? c'est quoi le resultat qui devait apparaitre ? chez moi c'est le bazzard
merci

14

le coin noir c'est normal, mais tu retrouves la même forme mais en blanc à d'autres endroits sur l'image filtrée : genre derrière le type qui est devant la colonne la plus à gauche...
onlymed (./13) :
MatriceImgROut[h][w] = MatriceImgR[h/2][w/2] ?? c'est quoi le resultat qui devait apparaitre ? chez moi c'est le bazzard
merci

ben ça devrait être juste le quart haut-gauche de l'image zoomé, donc c'est qu'il y a un bug (genre t'as pas échangé largeur et hauteur de l'image ?)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

15

Ah oui javais pas vu mais en si il y'avait des probleme de taille jpense que l'image serai decaler ...

euh je ne sais pas si ca ce qui est demander :
for (h = 0 ; h < length ; h++)
  for (w = 0 ; w < width ; w++)
  {

	
    MatriceImgROut[h][w] = 0 ;
    MatriceImgVOut[h][w] = 0 ;
    MatriceImgBOut[h][w] = 0 ;


MatriceImgROut[h][w] = MatriceImgR[h+2/2][w+2/2];
MatriceImgVOut[h][w] = MatriceImgV[h+2/2][w+2/2];
MatriceImgBOut[h][w] = MatriceImgB[h+2/2][w+2/2];
  }


// Le +2 car mon image sur les matrices est ( resultat la même image du depart ) 
00000
0xxx0
0xxx0
00000

// +1 peut etre ? image de droite ? (le morceau gauche  de l'image se deplace du coté droit )



e3NS

16

h+2/2 != (h+2)/2 trinon là tu ne zoomes rien du tout...

si tu préfères sinon tu peux juste décaler l'image d'un pixel vers le haut ou vers la droite, et vérifier que ça décale bien d'un seul pixel...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

Oups desolé pour cela aie aie aie la téte .

ca zoom pas ca detruit l'image irreconessable . vous etes sur linux ? je peut vous envoyer mon code peut etre que vous voyez plus clair parsque j'ai pratiquement tout tester rien a faire :s

18

je suis pas sous linux et j'aurais la flemme de regarder de toute façon tongue
mais c'est pas très compliqué : puisque 2/2=1, ./15 devrait être l'image de départ décalée d'un pixel vers le bas et vers la droite (i.e. dans la représentation en mémoire ça devrait être décalé de LARGEUR+1 cellules), or manifestement c'est pas le cas, ça a l'air d'être décalé vers la droite d'un nb de pixels à peu près égal à la hauteur de l'image (décalage de HAUTEUR+1 cellules) donc je confirme ce que j'ai dit dans ./14 : tu as sûrement échangé largeur et hauteur...


(euh sinon pour ce qui est du vouvoiement la norme sur ce forum est le tutoiement ^^)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

19

J'ai eu cette reponse mais je ne l'ai pas compris :
tu appliques ton filtre de ma nière non centrée !!! Tu parcours ton filtre de 0 à 2 et tu l'appliques tel quel alors que pour le centrer il faut l'appliquer de -1 à 1. Mais comme on ne peut définir d'indice négatifs, il te faudrait l'appliquer de 0 à 2 et décaler en mettant un -1.

autrement je me dit si javait echanger hauteur et largeur alors automatiquement en affichant l'image elle sera decaler ou même illisible ? non ?
je regarde tout ca et je te tien au courant tongue

20

non, si tu échanges hauteur et largeur dans l'image de départ *et* dans l'image d'arrivée ça se verra pas tant que tu ne fais aucun décalage ^^

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

21

Si je les avait inversé je pense que le resultat aurait été clair vu que j'aurai une image de dimension differente que celle en entrée non ?

voila en fait le programme acctuel

  /*--recuperation de l'entete--*/
  fgets(stringTmp1,100,fic);
  fgets(stringTmp2,100,fic);
  fscanf(fic,"%d %d",&length,&width);
  fscanf(fic,"%d\n",&ta3);

  /*--affichage de l'entete--*/
  printf("\n\n--Entete--");
  printf("\n----------");
  printf("\n%s%s%d %d \n%d\n",stringTmp1,stringTmp2,length,width,ta3);
  MatriceImgR=malloc_matrice_2d(length+2,width+2);
  MatriceImgV=malloc_matrice_2d(length+2,width+2);
  MatriceImgB=malloc_matrice_2d(length+2,width+2);

// ajout de ligne 0000000  pour entourer l'image  ( 1ere ligne et derniere )

for(i=0;i<length+2;i++)
{
     MatriceImgR[0][i]=0;
     MatriceImgV[0][i]=0;
     MatriceImgB[0][i]=0;
     MatriceImgR[width+1][i]=0;
     MatriceImgV[width+1][i]=0;
     MatriceImgB[width+1][i]=0;
 
}

// pareille pour les colonnes 

for(j=1;j<width+1;j++)
{
     MatriceImgR[j][0]=0;
     MatriceImgV[j][0]=0;
     MatriceImgB[j][0]=0;
     MatriceImgR[j][length+1]=0;
     MatriceImgV[j][length+1]=0;
     MatriceImgB[j][length+1]=0;
 
}


  /*--chargement dans la matrice--*/
  for(i=1;i<length+1;i++) for(j=1;j<width+1;j++)  
    { 
     fscanf(fic,"%d",&varr);
     fscanf(fic,"%d",&varv); 
     fscanf(fic,"%d",&varb); 
     MatriceImgR[i][j]=varr;
     MatriceImgV[i][j]=varv;
     MatriceImgB[i][j]=varb;  
    }





puis l'application du masque ici : FLOU :

{
  MatriceImgROut=malloc_matrice_2d(length,width);
  MatriceImgVOut=malloc_matrice_2d(length,width);
  MatriceImgBOut=malloc_matrice_2d(length,width);
  coefficients=malloc_matrice_2d(3,3);



int h , w , i , j ;



    coefficients[0][0] = 1 ;
    coefficients[0][1] = 1;
    coefficients[0][2] = 1 ;
    coefficients[1][0] = 1;
    coefficients[1][1] = 1;
    coefficients[1][2] = 1 ;
    coefficients[2][0] = 1 ;
    coefficients[2][1] = 1 ;
    coefficients[2][2] = 1 ;

for (h = 0 ; h < width ; h++)
  for (w = 0 ; w < length  ; w++)
  {

	
     MatriceImgROut[h][w] = 0 ;
     MatriceImgVOut[h][w] = 0 ;
     MatriceImgBOut[h][w] = 0 ;






     for (i = 0 ; i <=2  ; i++)
       for (j = 0 ; j <=2 ; j++)
 	{
         MatriceImgROut[h][w] += coefficients[i][j] * MatriceImgR[h+i][w+j] ;
         MatriceImgVOut[h][w] += coefficients[i][j] * MatriceImgV[h+i][w+j] ;
         MatriceImgBOut[h][w] += coefficients[i][j] * MatriceImgB[h+i][w+j] ;
 	}
 
	MatriceImgROut[h][w] /= 9 ;
	MatriceImgVOut[h][w] /= 9 ;
	MatriceImgBOut[h][w] /= 9 ;

 	if(MatriceImgROut[h][w]<0)
        	MatriceImgROut[h][w]=0;
 	else 
 		if(MatriceImgROut[h][w]>255)
          	MatriceImgROut[h][w]=255;

 	if(MatriceImgVOut[h][w]<0)
        	MatriceImgVOut[h][w]=0;
 	else 
 		if(MatriceImgVOut[h][w]>255)
          	MatriceImgVOut[h][w]=255;

 	if(MatriceImgBOut[h][w]<0)
        	MatriceImgBOut[h][w]=0;
 	else 
 		if(MatriceImgBOut[h][w]>255)
          	MatriceImgBOut[h][w]=255;


  }



et pour finir sauvegarder dans la nouvelle image :

 /*--sauvegarde de l'entete--*/
  fprintf(fic,"P3");
  fprintf(fic,"\n# IMG Created %s",ctime(&tm));
  fprintf(fic,"%d %d",length,width);
  fprintf(fic,"\n255\n");

  /*--enregistrement--*/
  for(i=0;i<length;i++) 
  for(j=0;j<width;j++) 
    {
     fprintf(fic,"%d\n",(int)MatriceImgROut[i][j]);
     fprintf(fic,"%d\n",(int)MatriceImgVOut[i][j]);
     fprintf(fic,"%d\n",(int)MatriceImgBOut[i][j]);

    }
       
  /*--fermeture fichier--*/
   fclose(fic); 


si tu vois quelque chose ca m'evitera encore 10h de casse tête ouf

22

onlymed (./21) :
Si je les avait inversé je pense que le resultat aurait été clair vu que j'aurai une image de dimension differente que celle en entrée non ?

Ben non, si tu les inverses dans la routine d'entrée et dans la routine de sortie la dimension reste la même...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

23

j'ai inversé dans les deux mais rien a faire toujours le méme probleme a croire que tout est correct enfin apart le resultat :s

24

ton code de lecture/écriture du contenu de l'image inverse i et j (ou width et length pour les bornes de i et j, selon le format du fichier)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

25

voici le resultat en inversant width et length7q9N

26

il faut l'inverser dans la lecture *et* dans l'écriture

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

27

Ah oui j'avais pas activé la fonction .
ca me donne ce resultat ( effet flou visible mais avec un decalage que je vois pas la provenence )WuEp

28

Les variables length et width sont visiblement inversées lors de la lecture et écriture du fichier.
Dans le format PPM, la largeur de l'image en pixels est inscrite avant la hauteur.
avatar

29

bien justement ca me parait un peut louche puisque mon image été 300 225 et maintenant que j'ai inversé eh bien le resultat c'est que j'ai perdu un morceau qui a été remplacer par un autre ( coté droit gauche == )

30

Probleme resolu , en effet c'était un inverssement de length et width lors de l'allocation memoire pour les matrice qui aurant les resultats calcule de filtre !! mais euh ne deverai je avoir une SIGMENTATIION ERROR vu que c'est pas des images carrée ? bizzard