[c] Image : passage d'une image BMP RVB en NB - traitement de l'image encore et toujours

Salut les programmeurs !

voilà je veux enregistrer mon image RVB en Noir&Blanc mais il doit avoir quelque chose queje ne fais pas car mon fichier est impossible à ouvrir !
donc si vous pouviez y jetter un oeil voir 2 je suis pas contre !
Merci !


//---------------------------------------------------------------------------
// L'entête décrit une image monochrome 8 bits
static void _InitEntete (int tailleX, int tailleY, int nbOctetsParPixel)
//---------------------------------------------------------------------------
{
    //initialiser le BITMAPFILEHEADER
	_bmpFileHeader.bfType = ('M'<<8)|'B';
    //offset de l'image dans le fichier (taille de l'entête)
	_bmpFileHeader.bfOffBits = sizeof(_bmpFileHeader) +
          	sizeof(_bmpInfoHeader);
    //taille totale du fichier (entête + image)
	_bmpFileHeader.bfSize = _bmpFileHeader.bfOffBits +
            	abs(tailleX*tailleY*nbOctetsParPixel);
	_bmpFileHeader.bfReserved1 = 0;
    _bmpFileHeader.bfReserved2 = 0;

    //initialiser le BITMAPINFOHEADER
	_bmpInfoHeader.biSize=sizeof(BITMAPINFOHEADER);
	_bmpInfoHeader.biWidth=tailleX;
	_bmpInfoHeader.biHeight=tailleY;
	_bmpInfoHeader.biPlanes=1;
	_bmpInfoHeader.biBitCount=8*nbOctetsParPixel;
	_bmpInfoHeader.biCompression=BI_RGB;
	_bmpInfoHeader.biSizeImage=abs(tailleX*tailleY*nbOctetsParPixel);
	_bmpInfoHeader.biXPelsPerMeter=0;
	_bmpInfoHeader.biYPelsPerMeter=0;
	_bmpInfoHeader.biClrUsed=0;
	_bmpInfoHeader.biClrImportant=0;
	
}

 //structure BITMAPINFO monochrome;
static struct {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[256];
    } bmpInfoMono =
    {{
	sizeof(BITMAPINFOHEADER),	//biSize
	0,      	//biWidth
	0,      	//biHeight
	1,      	//biPlanes
	8,      	//biBitCount
	BI_RGB,      //biCompression
	0,      	//biSizeImage
	0,      	//biXPelsPerMeter
	0,      	//biYPelsPerMeter
	256,      //biClrUsed
	0      	//biClrImportant
	},
	0};


//---------------------------------------------------------------------------
int BMP_Enregistrer (const char *nomFichier, const unsigned char* pImage,
      int tailleX, int tailleY, int nbOctetsParPixel)
//---------------------------------------------------------------------------
{

	int F;
	double t0, t;
	char mess[100];

	
	//initialiser l'entete si nécessaire
/*	if ((_bmpInfoHeader.biWidth!=tailleX) ||
  (_bmpInfoHeader.biHeight!=tailleY) ||
  (_bmpInfoHeader.biBitCount!=8*nbOctetsParPixel)) {
  _InitEntete(tailleX, tailleY, nbOctetsParPixel);
  OutputDebugString("[IRCMesureur] _InitEntete()");
  //mode de fermeture des fichiers : CloseFile retourne sans vérifier l'écriture
  SetCommitMode(0);
  }  */
	if ((bmpInfoMono.bmiHeader.biWidth!=tailleX) ||
  (bmpInfoMono.bmiHeader.biHeight!=tailleY) ||
  (bmpInfoMono.bmiHeader.biBitCount!=8*nbOctetsParPixel)) 
	{
  	bmpInfoMono.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
  	bmpInfoMono.bmiHeader.biWidth=tailleX;
  	bmpInfoMono.bmiHeader.biHeight=tailleY;
  	bmpInfoMono.bmiHeader.biPlanes=1;
  	bmpInfoMono.bmiHeader.biBitCount=8;
  	bmpInfoMono.bmiHeader.biCompression=BI_RGB;
  	bmpInfoMono.bmiHeader.biSizeImage=abs(tailleX*tailleY);
  	bmpInfoMono.bmiHeader.biXPelsPerMeter=0;
  	bmpInfoMono.bmiHeader.biYPelsPerMeter=0;
  	bmpInfoMono.bmiHeader.biClrUsed=256;
  	bmpInfoMono.bmiHeader.biClrImportant=256;
  
  	//mode de fermeture des fichiers : CloseFile retourne sans vérifier l'écriture
  	SetCommitMode(0);
	}
  
	
  
	t0 = Timer();
	F = OpenFile (nomFichier, VAL_WRITE_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);
	if (F<0) return -1;
	
	//remplissage de la table de couleurs N&B au premier appel
	if (!bmpInfoMono.bmiColors[1].rgbBlue) 
	{
  int i;
  for (i=0; i<256;i++) 
  {
  	bmpInfoMono.bmiColors[i].rgbBlue = i;
  	bmpInfoMono.bmiColors[i].rgbGreen = i;
  	bmpInfoMono.bmiColors[i].rgbRed = i;
  	bmpInfoMono.bmiColors[i].rgbReserved = 0;
  }
	}

/*	WriteFile(F, (char*)&_bmpFileHeader, sizeof(_bmpFileHeader));
	WriteFile(F, (char*)&_bmpInfoHeader, _bmpInfoHeader.biSize);
	WriteFile(F, pImage, _bmpInfoHeader.biSizeImage);   */
	WriteFile(F, (char*)&bmpInfoMono.bmiHeader, sizeof(bmpInfoMono.bmiHeader));
	WriteFile(F, (char*)&bmpInfoMono.bmiHeader, bmpInfoMono.bmiHeader.biSize);
	WriteFile(F, pImage, bmpInfoMono.bmiHeader.biSizeImage);
	t = Timer()-t0;
	sprintf(mess,"[IRCMesureur] BMP_Enregistrer() Durée copie donnée = %6.3fs", t);
	OutputDebugString(mess);
	CloseFile(F);
	t = Timer()-t0;
	sprintf(mess,"[IRCMesureur] BMP_Enregistrer() Durée enregistrement = %6.3fs", t);
	OutputDebugString(mess);
	return 0;  
}

Ton image d’entrée (pImage) est comment? RGB?

En fait si j’ai bien compris tu passes par une table de correspondance n&b mais je ne vois pas ou tu fais la conversion de tes données, de 24bit en 8bit…

Aparrement tu n’enregistre que le tiers de ton image…

en fait mon image d’entrée pImage est de couleur !
juste avnt de rentrer dans cette fonction je sépare les couches rouges et vertes pour créer 2 fichiers séparés !
mais le probleme doit etre au niveau de la palette de couleur je pense …

Ce que tu veux faire c’est enregistrer les couches rvb en 3 fichiers n&b non?

Peut être ça viendrait de là:


bmpInfoMono.bmiHeader.biBitCount!=8*nbOctetsParPixel

Ton nbOctetsParPixel doit valoir 1 si c’est une image n&b

oui c’est que je passe en paramètre !
sinon je veux enregistrer les couches rouges et vertes en N&B et c’est tou la bleue je m’en tape !

je l’ai fait pour un projet il faut faire (R^2+G^2+B^2)^(0.5) => ca te donne une matrice en N&B (codé sous 8 bits)

c’est marrant, j’aurais fait une bête moyenne:
(r+g+b)/3
:neutre:

non en fait il veut que le bleu et que le rouge

Donc en fait ça dépent comment sont stokées les données en mémoire (entrelacé ou non)

Entrelacé:


unsigned char * imgRGB;
int size;

unsigned char * imgR=(unsigned char*)malloc(size/3);
unsigned char * imgG=(unsigned char*)malloc(size/3);
unsigned char * ptr=imgRGB,*ptrR=imgR,ptrG=imgG;

int i=size;
while(i--)
{
*(ptrR++)=*(ptr++); //rouge
*(ptrG++)=*(ptr++); //vert
ptr++; //bleu (on s'en fous)
}

non-entrelacé:


unsigned char * imgRGB;
int size;

unsigned char * imgR=(unsigned char*)malloc(size/3);
unsigned char * imgG=(unsigned char*)malloc(size/3);

int i;
memcpy(imgR,img,size/3);
memcpy(imgG,img+size/3,size/3);

Dans les 2 cas, imgR et imgB sont des buffers n&b correspondants aux données Rouge et Vert

pour avoir une image correcte en N&B je lui conseille de prendre les 3 matrices RGB (deja que le resultat est bof :/)
mes images venaient d’une webcam elles n’étaient pas entrelacées je les recuperer dans un seul buffer (tableau) à la suite :stuck_out_tongue:

non non et non je veux pas du bleu c’est une donnée qui m’est d’aucune utilité !
Par contre j’ai un peu progresser dans mon code :
j’arrive à obtenir mes 2 plans mais il s’enregistre pas en N&B maintenant ! c’est le seul Hic !
Je vais vous mettre le code qui s’est un peu simplifié :slight_smile:

ma fonction d’enregistrement d’image


//---------------------------------------------------------------------------
int BMP_Enregistrer (const char *nomFichier, const unsigned char* pImage,
      int tailleX, int tailleY)
//---------------------------------------------------------------------------
{

	int F;
	double t0, t;
	char mess[100];


	//initialiser l'entete si nécessaire
	if ((_bmpInfoHeader.bmiHeader.biWidth!=tailleX) ||
  (_bmpInfoHeader.bmiHeader.biHeight!=tailleY) ||
  (_bmpInfoHeader.bmiHeader.biBitCount!=8)) {
  _InitEntete(tailleX, tailleY);
  //mode de fermeture des fichiers : CloseFile retourne sans vérifier l'écriture
  SetCommitMode(0);
  }
	t0 = Timer();
	F = OpenFile (nomFichier, VAL_WRITE_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);
	if (F<0) return -1;
	WriteFile(F, (char*)&_bmpFileHeader, sizeof(_bmpFileHeader));
	WriteFile(F, (char*)&_bmpInfoHeader, _bmpInfoHeader.bmiHeader.biSize);
	WriteFile(F, pImage, _bmpInfoHeader.bmiHeader.biSizeImage); 
	WriteFile(F, (char*)&_bmpInfoHeader.bmiHeader, sizeof(_bmpInfoHeader.bmiHeader));
	WriteFile(F, (char*)&_bmpInfoHeader.bmiHeader, _bmpInfoHeader.bmiHeader.biSize);
	WriteFile(F, pImage, _bmpInfoHeader.bmiHeader.biSizeImage); //*/
	t = Timer()-t0;
	sprintf(mess,"[IRCMesureur] BMP_Enregistrer() Durée copie donnée = %6.3fs", t);
	OutputDebugString(mess);
	CloseFile(F);
	t = Timer()-t0;
	sprintf(mess,"[IRCMesureur] BMP_Enregistrer() Durée enregistrement = %6.3fs", t);
	OutputDebugString(mess);
	return 0;
}

mes 2 structures :


//header pour fichier bmp
static BITMAPFILEHEADER	_bmpFileHeader;
//static BITMAPINFOHEADER	_bmpInfoHeader;
 //structure BITMAPINFO monochrome;
static struct {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[256];
    } _bmpInfoHeader =
    {{
	sizeof(BITMAPINFOHEADER),	//biSize
	0,      	//biWidth
	0,      	//biHeight
	1,      	//biPlanes
	8,      	//biBitCount
	BI_RGB,      //biCompression
	0,      	//biSizeImage
	0,      	//biXPelsPerMeter
	0,      	//biYPelsPerMeter
	256,      	//biClrUsed
	0      	//biClrImportant
	},
	0};

//---------------------------------------------------------------------------
// L'entête décrit une image monochrome 8 bits
static void _InitEntete (int tailleX, int tailleY)
//---------------------------------------------------------------------------
{
    //initialiser le BITMAPFILEHEADER
	_bmpFileHeader.bfType = ('M'<<8)|'B';
    //offset de l'image dans le fichier (taille de l'entête)
	_bmpFileHeader.bfOffBits = sizeof(_bmpFileHeader) +
          	sizeof(_bmpInfoHeader);
    //taille totale du fichier (entête + image)
	_bmpFileHeader.bfSize = _bmpFileHeader.bfOffBits +
            	abs(tailleX*tailleY);
	_bmpFileHeader.bfReserved1 = 0;
    _bmpFileHeader.bfReserved2 = 0;

    //initialiser le BITMAPINFOHEADER
	_bmpInfoHeader.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	_bmpInfoHeader.bmiHeader.biWidth=tailleX;
	_bmpInfoHeader.bmiHeader.biHeight=tailleY;
	_bmpInfoHeader.bmiHeader.biPlanes=1;
	_bmpInfoHeader.bmiHeader.biBitCount=8;
	_bmpInfoHeader.bmiHeader.biCompression=BI_RGB;
	_bmpInfoHeader.bmiHeader.biSizeImage=abs(tailleX*tailleY);
	_bmpInfoHeader.bmiHeader.biXPelsPerMeter=0;
	_bmpInfoHeader.bmiHeader.biYPelsPerMeter=0;
	_bmpInfoHeader.bmiHeader.biClrUsed=256;
	_bmpInfoHeader.bmiHeader.biClrImportant=0;    
	
  //remplissage de la table de couleurs N&B au premier appel
	if (!_bmpInfoHeader.bmiColors[1].rgbBlue) {
  int i;
  for (i=0; i<256;i++) {
  	_bmpInfoHeader.bmiColors[i].rgbBlue = i;
  	_bmpInfoHeader.bmiColors[i].rgbGreen = i;
  	_bmpInfoHeader.bmiColors[i].rgbRed = i;
  	_bmpInfoHeader.bmiColors[i].rgbReserved = 0;
  	}
  } 
}

et voici les appels de la fonction enregistrer :


 BMP_Enregistrer ("img/Couche Verte.bmp", bufferVert,bmpInfoHeader.biWidth/2, bmpInfoHeader.biHeight/2);
  BMP_Enregistrer ("img/Couche Rouge.bmp", bufferRouge,bmpInfoHeader.biWidth/2, bmpInfoHeader.biHeight/2);