Problem lecture/ecriture fichier bmp [Résolu]

Signaler
Messages postés
12
Date d'inscription
vendredi 9 mai 2008
Statut
Membre
Dernière intervention
4 janvier 2011
-
Messages postés
12
Date d'inscription
vendredi 9 mai 2008
Statut
Membre
Dernière intervention
4 janvier 2011
-
Bonjour,
je suis en train de lire et écrire avec une image en bmp
ma fonction d'écriture et de lecture fonctionne bien uniquement avec des image de dimension multiple de 2 par exemple:
512*512 ou 256*190,500*344 etc...
mais par avec une image de 501*344 il y a des problèmes dans la recopie de mon image.
Voici la fonction de lecture:

TimageC::TimageC(unsigned char *name_f):Timage(name_f)
{	FILE * fdat;
unsigned char temp,P6[3],buff[4],image_type = 0,*buff_temp,modulo;
unsigned char * Source_c;
pixel_RGB *Source;
Char_To_Int conv;
unsigned int i,size,offset;
fdat = fopen((const char*)name_f,"rb");
if (!fdat)
{	printf("\n !Probleme en lecture de %s ! \n",name_f);
nbcol=0;
nblig=0;
comment[0]='#';
max_val=0;
}
else
{	//recherche du format .bmp ou .pgm
for(i=0;name_f[i]!=0;i++)
{	if(name_f[i]=='.')
{	if((name_f[i+1]=='b')&&(name_f[i+2]=='m')&&(name_f[i+3]=='p')) image_type=BMP_24_TYPE_FILE;
if((name_f[i+1]=='p')&&(name_f[i+2]=='p')&&(name_f[i+3]=='m')) image_type=PPM_TYPE_FILE;
}
}
switch(image_type)
{	case BMP_24_TYPE_FILE:
{	fread(buff,sizeof(unsigned char),2,fdat);
fread(conv.buf_c,sizeof(unsigned char),4,fdat);
size=conv.buf_i;
fread(buff,sizeof(unsigned char),4,fdat);//Application specific
fread(buff,sizeof(unsigned char),4,fdat);//offset where the bitmap data (pixels) can be found
fread(conv.buf_c,sizeof(unsigned char),4,fdat);//number of bytes in the header (from this point)
offset=conv.buf_i;
fread(conv.buf_c,sizeof(unsigned char),4,fdat);//width of the bitmap in pixels
nbcol=conv.buf_i;
fread(conv.buf_c,sizeof(unsigned char),4,fdat);//height of the bitmap in pixels
nblig=conv.buf_i;
buff_temp=new unsigned char[offset-12];
fread(buff_temp,sizeof(unsigned char),offset-12,fdat);
delete []buff_temp;
//lecture de l'image
Source_c = new unsigned char [nbcol*nblig*3+((nbcol%4)*nblig)];
for(unsigned int i=0;i<nbcol*nblig*3+((nbcol%4)*nblig);i++)Source_c[i]=0;
size=fread(Source_c,1,nbcol*nblig*3+((nbcol%4)*nblig), fdat);
fclose(fdat);
PixelC=new TPixelC**[nbcol];
for(unsigned int x=0;x<nbcol;x++) 
{	PixelC[x] = new TPixelC*[nblig];
for(unsigned int y=0;y<nblig;y++)
{	modulo=nbcol%4*x;
PixelC[x][y] = new TPixelC(Source_c[((y*nbcol)+x)*3+2+modulo],Source_c[((y*nbcol)+x)*3+1+modulo],Source_c[((y*nbcol)+x)*3+modulo]);
}
}				
max_val=255;
comment[0]=0;
delete []Source_c;
printf("fin de la lecture\n");
break;
}
case PPM_TYPE_FILE:
{	/* Recup de P6 */
fread(P6,1,2,fdat);
fread(&temp,1,1,fdat);
i=0;
while (temp ' ' || temp '\n' || temp == '#')
{	if (temp == '#') /* On est tombe sur un caractere */
{	comment[i] = temp;
i++;
while (temp != '\n')
{	comment[i] = temp;
i++;
fread(&temp,1,1,fdat);
}	
}
fread(&temp,1,1,fdat);
}
/* Recup de la largeur */
nbcol = 0;
while ((temp >= '0') && (temp <= '9'))
{	nbcol = nbcol * 10;
nbcol += (temp - '0');
fread(&temp,1,1,fdat);
}
/* Saute les blancs */
while (temp ' ' || temp '\n' || temp == '#') 
{	if (temp == '#')
{	while (temp != '\n')	fread(&temp,1,1,fdat);
}
fread(&temp,1,1,fdat);
}
/* Recup de la hauteur */
nblig = 0;
while ((temp >= '0') && (temp <= '9'))
{	nblig = nblig * 10;
nblig += (temp - '0');
fread(&temp,1,1,fdat);
}
/* Saute les blancs et autres */
while (temp ' ' || temp '\n' || temp == '#') 
{
if (temp == '#')
{	while (temp != '\n')	fread(&temp,1,1,fdat);
}
fread(&temp,1,1,fdat);
}
/* Recup valeur max */
max_val = 0;
while ((temp >= '0') && (temp <= '9'))
{	max_val = max_val * 10;
max_val += (temp - '0');
fread(&temp,1,1,fdat);
}
//fread(&temp,1,1,fdat);
/* Lecture du tableau de pixels */
Source = new pixel_RGB [nblig*nbcol];
fread(Source, sizeof(pixel_RGB), nblig*nbcol, fdat);
fclose(fdat);

PixelC=new TPixelC**[nbcol];
for(unsigned int x=0;x<nbcol;x++) 
{	PixelC[x] = new TPixelC*[nblig];
for(unsigned int y=0;y<nblig;y++)
{	PixelC[x][y] = new TPixelC(
Source[(y*nblig)+x].r,
Source[(y*nblig)+x].g,
Source[(y*nblig)+x].b);
}
}
delete []Source;
break;
}
}
}
}
//-----------------------------------------------------------------

Cette fonction peu lire des fichier BMP et PPM
voici maintenant la fonction d'ecriture:
unsigned char TimageC::Save_file(unsigned char *name_file)
{
FILE * fdat;
int taille;
unsigned char *temp,image_type,modulo;
Char_To_Int conv;
pixel_RGB *Pixel_tab;
Pixel_tab=new pixel_RGB [nbcol*nblig];
fdat = fopen((const char *)name_file,"wb");
if (!fdat)
{
printf("\n !Probleme en ecriture de %s ! \n",name_file);
return 0;
}else
{	//recherche du format .bmp ou .pgm
for(unsigned int i=0;name_file[i]!=0;i++)
{	if(name_file[i]=='.')
{	if((name_file[i+1]=='b')&&(name_file[i+2]=='m')&&(name_file[i+3]=='p')) image_type=BMP_24_TYPE_FILE;
if((name_file[i+1]=='p')&&(name_file[i+2]=='p')&&(name_file[i+3]=='m')) image_type=PPM_TYPE_FILE;
}
}
switch(image_type)
{	case BMP_24_TYPE_FILE:
{	
fwrite("BM",sizeof(unsigned char),2,fdat);
conv.buf_i=nbcol*nblig*3+((nblig%4)*nbcol)+54;//size of bitmap file
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//write size of bitmap file
conv.buf_i=0;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//Application specific
conv.buf_i=54;//54 offset
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//offset where the bitmap data (pixels) can be found
conv.buf_i=40;//40 number of bytes in the header
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//number of bytes in the header (from this point)
conv.buf_i=nbcol;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//width of the bitmap in pixels
conv.buf_i=nblig;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//height of the bitmap in pixels
conv.buf_c[0]=0x01;
conv.buf_c[1]=0;
conv.buf_c[2]=0x18;//24bits/pixel
conv.buf_c[3]=0;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//number of color plane being used,number pixels/bit
conv.buf_i=0;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//BI_RGB,no compression used
conv.buf_i=0;//16
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//size of the raw BMP data (after this header)
conv.buf_c[0]=0;//0x13
conv.buf_c[1]=0;//0x0B
conv.buf_c[2]=0x00;
conv.buf_c[3]=0x00;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//the horizontal resolution
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//the vertical resolution
conv.buf_i=0;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//number of color in the palette
conv.buf_i=0;
fwrite(conv.buf_c,sizeof(unsigned char),4,fdat);//0 importante color(means all colors are important
//ecriture de l'image
temp=new unsigned char [nbcol*nblig*3+((nbcol%4)*nblig)];
//for(i=0;i<nbcol*nblig*3+((nblig%4)*nbcol);i++)temp[i];
for(unsigned int x=0;x<nbcol;x++) 
{	
for(unsigned int y =0;y <nblig;y++)
{	modulo=((nbcol%4)*x);
temp[((y*nbcol)+x)*3+modulo]=PixelC[x][y]->B;
temp[(((y*nbcol)+x)*3)+1+modulo]=PixelC[x][y]->G;
temp[(((y*nbcol)+x)*3)+2+modulo]=PixelC[x][y]->R;
}
}
fwrite(temp,sizeof(unsigned char),nbcol*nblig*3+((nbcol%4)*nblig),fdat);
delete []temp;
fclose(fdat);
printf("fin de la l'ecriture\n");
break;
}
case PPM_TYPE_FILE:
{	
for(unsigned int x =0;x<nbcol;x++) 
{	
for(unsigned int y =0;y<nblig;y++)
{	Pixel_tab[(y*nblig)+x].r=PixelC[x][y]->R;
Pixel_tab[(y*nblig)+x].g=PixelC[x][y]->G;
Pixel_tab[(y*nblig)+x].b=PixelC[x][y]->B;
}
}
fprintf(fdat,"P6\n%s\n%d %d\n%d\n",comment,nbcol,nblig,max_val);
taille = (int)fwrite(Pixel_tab, sizeof(pixel_RGB),nbcol*nblig, fdat);
fclose(fdat);
break;
}
delete []Pixel_tab;
delete []temp;
}
return 1;
}
}
//-----------------------------------------------------------------

la fonction d'écriture peu ecrire en BMP ou en PPM
Le résultat de recopie d'image (lecture suivi d'une écriture).
introduit des pixels rouge, vert et bleu de façon régulière.

3 réponses

Messages postés
12
Date d'inscription
vendredi 9 mai 2008
Statut
Membre
Dernière intervention
4 janvier 2011

second probléme
la ligne:
modulo=((nbcol%4)*x);
n'est pas correct puisque c'est à chaque extrémité de ligne qu'il faut refaire le calage sur 1 multiple de 4 et non pas à chaque extremité de colone.
donc la ligne correcte est la suivante:
modulo=(nbcol%4)*y;
Messages postés
12
Date d'inscription
vendredi 9 mai 2008
Statut
Membre
Dernière intervention
4 janvier 2011

il n'y a pas un moyen d'insérer mon image de départ et d'arrivée afin que ce soit plus concret.
Messages postés
12
Date d'inscription
vendredi 9 mai 2008
Statut
Membre
Dernière intervention
4 janvier 2011

Finalement j'ai trouvé 1 problème la variable modulo été déclaré en unsigned char tandis qu'elle peu dépasser 255 donc je l'ai mis en unsigned int.
Cela change le résultat.Il est meilleur mais ce n'est toujours pas ça.