Extrahieren der Bilder Daten aus einer BMP Datei

Hallo Zusammen,

ich habe ein C Program geschrieben um die RGB Werte einer 24 Bits Tiefe BMP Datei zu erhalten. Es scheint gut für „einfaches“ Bild zu funktionnieren (das heisst, für Bilder mit nur einer Farbe, ich habe für ein weiss bzw. schwarz Bilder geprüft). Aber es erzeugt nicht erwarteten Ergebnisse für komplizierte Bildern.
Hier sind die Hauptschritte zusammengefasst :

  1. BMP Daten vom Datein einlesen,
  2. Pointer zu File auf Beginn der Bildsdateien zu plazieren,
  3. Anzeigen des Inhalts des Buffers, mit RGB Werten

Bsp mit weissem Bild :
(…)
n_frame 189 R 255 G 255 B 255 #
n_frame 192 R 255 G 255 B 255 #
n_frame 195 R 255 G 255 B 255 #
(…)
OK. Und sowohl Ok mit schwarzem Bild.

Aber bei Halb schwarz halb weiss Bild, erhalte ich nur 0 0 0, das heisst, es sieht als ob, das Bild nur schwarz wäre.

Hier sind die Schlüssel-Linie von meinem Code :

fseek (pFile , 0 , SEEK_END); // obtain file size
lSize = ftell (pFile);
rewind (pFile); // Replace the pointer to the beginning of the file
fseek (pFile,10,SEEK_SET); // Place the pointer to the „offset“ of image data
printf(„offset_image = %d \n“,offset_image=fgetc(pFile));
fseek (pFile,offset_image,SEEK_SET);

frame_total = (unsigned char*) malloc (3 * 1024 * sizeof(unsigned char)); // allocate memory to contain the BMP data

if(frame_total == NULL)
{
printf(„Error by buffer allocation \n“);
exit (2);
}

number_of_element_read=fread (frame_total,1,3 * 1024,pFile); // copy the file into the buffer. The whole file is loaded in the buffer.

printf(„FREAD VALUE IS : %d \n“,number_of_element_read);

// Printing pixel values
for(n_frame=0;n_frame

Ok, habe ich die Lösung selbst gefunden (Ich hatte einige Fehler in MALLOC und in der Lange der Tabelle gemacht).
Für die die interessiert sind :
(Vorsicht ! Gültig nur für 24 BMP, 1024*1024)

#include
#include
#include // to use malloc (memory allocation)
//#include // to work with BMP

#define PHOTOBW „C:\C+±Programme\Guilhem_Martin\test01.bmp“
// TEST SEEMS OK FOR ENTIRE WHITE FUNCTION OR ENTIRE BLACK FUNCTION
#define PHOTOBW2 „C:\C+±Programme\Guilhem_Martin\halfblack_halfwhite_totest_coordinatesystem_and_getlev.bmp“
#define PHOTOBW3 „C:\C+±Programme\Guilhem_Martin\halfblack_halfwhite_reverse.bmp“
#define PHOTOBW4 „C:\C+±Programme\Guilhem_Martin\wasser486bmp10241024_centered_worked_b2.bmp“

void main()
{
FILE *pFile; // Pointer to the image file to process (to extract the drop profile from)
// unsigned short int* table_to_fill; // half black half white
// unsigned short int* frame; // The frame is supposed to store only image data (and not header information)
unsigned char * frame_total; // The frame is supposed to store the whole image file
unsigned char * frame_intensity; // (R+G+B)/3
// unsigned short int * frame_pixel; // Compute the R+G+B for one pixel
int n_frame; //long n_frame;
//unsigned short int lSize; // Causes error by execution
long lSize; // Size of the file to analyse (including both image and header data)
int number_of_element_read;
int offset_image;
int n_frame2=0;

// Notice !
// lSize : length of the file in bytes (8bits) :
// For instance 32 bits for lSize is 4 bytes
// buffer defined as (unsigned) short int (16bits ou 2 bytes)

//************OPENING AND SETTING UP FILE POINTER************//
//** fopen returns a pointer to the file, Opening the file in binary mode
//** Variables to be passed in parameter for fread
//** lSize : same size as the one displayed in the property dialog in the explorer
if((pFile=fopen(PHOTOBW4,„rb“))==0) printf(„Open file failed\n“); // Read only Opening BMP file

fseek (pFile , 0 , SEEK_END); // obtain file size
lSize = ftell (pFile);
rewind (pFile); // Replace the pointer to the beginning of the file
// fseek (pFile,55,SEEK_SET); // Place the cursor to the beginning of BMP data (54 bytes are designed for the header)
fseek (pFile,10,SEEK_SET);

printf(„offset_image = %d \n“,offset_image=fgetc(pFile));

fseek (pFile,offset_image,SEEK_SET);

//mybmp=pFile;//mybmp//biBitCount

frame_total = (unsigned char*) malloc (3 * 1024 * 1024 * sizeof(unsigned char)); // allocate memory to contain the whole file.
frame_intensity = (unsigned char*) malloc (1024 * 1024 * sizeof(unsigned char));

if(frame_total == NULL)
{
printf(„Error by buffer allocation \n“);
exit (2);
}

number_of_element_read=fread (frame_total,1,3 * 1024 * 1024 * sizeof(unsigned char),pFile); // copy the file into the buffer. The whole file is loaded in the buffer.
// 3*1024*1024 = 3145728

printf(„FREAD VALUE IS : %d \n“,number_of_element_read);
printf(„FREAD/3 VALUE IS : %d \n“,number_of_element_read/3);

//printf("%d %d %d \n",frame_total[0],frame_total[1],frame_total[2]);
//printf("%d %d %d \n",frame_total[3069],frame_total[3070],frame_total[3071]);

// frame_total[3069]=(frame_total[3070]+frame_total[3071])/2-58; Ca ca marche
/*
for(n_frame=0;n_frame[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Anregungen aus professioneller Windows-Programmier
Vielleicht hilft Ihnen auch folgendes Code-Fragment etwas weiter, mit dem ich auf relativ knappe Weise eine komplette Bitmap aus ihrer Datei in einen internen Byte-Speicherbereich formatiert einlese.

void CBildverarbeitungDoc::open_mouth:nDateiQuickload()
{
//wie hier neben Dateiöffnung auch noch Fileauswahl über Standarddialog CFileDialog einzubauen???;
CFile file; //hierzu alle möglichen neuen Auswahldialoge zu schaffen!;
CFileException fe; //Bedeutung?, hierauf zu verzichten?;
LPCTSTR lpszPathName;
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
LPSTR pDIB;

lpszPathName = „D:\image master\notefilenr.bmp“;
//alternativ auch neue vereinfachte Fileauswahlmöglichkeiten und -dialoge zu schaffen;
if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe)){MessageBox(NULL, „fopen failed“, NULL, MB_ICONINFORMATION | MB_OK);return;}

DeleteContents();
BeginWaitCursor();
// replace calls to Serialize with ReadDIBFile function
TRY
{ //m_hDIB = ::ReadDIBFile(file);
dwBitsSize = file.GetLength();
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)){return;}
if (bmfHeader.bfType != ((WORD) (‚M‘ GetHDIB();
if (hDIB == NULL){
AfxMessageBox(„aktuelles Dokument ohne Bitmap!“);
return;
}

if (pDoc->GetDocPalette() != NULL){
AfxMessageBox(„Problem mit unerwünschter Palette!“);
return;
}//wegen void kein Wert zurück!;

LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
cxDIB = lpbmi->biWidth; //(int) ::smiley:IBWidth(lpDIB);
cyDIB = lpbmi->biHeight;
lpBits = (LPBYTE) (lpDIB + *(LPDWORD)lpDIB + ::stuck_out_tongue:aletteSize(lpDIB));

if ( ((*(LPDWORD)(lpDIB)) == sizeof(BITMAPINFOHEADER)) )
wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else {
AfxMessageBox(„coreheader statt infoheader???“); return;
}

if (((wBitCount==24)||(wBitCount==32)) != 1)
{::GlobalUnlock((HGLOBAL) hDIB);
AfxMessageBox(„BitCount zu klein, 8 für sw oder Fehler?“);
return;
}
q = wBitCount/8;
to4=0;
if (wBitCount==24) to4 = (4 - ((3*cxDIB) % 4)) % 4;

//::GlobalUnlock((HGLOBAL) hDIB);
pDoc->UpdateAllViews(NULL);

AfxMessageBox(„DIB aus Dokument nun erst geladen und Parameter überprüft!“);

//nun Verarbeitung mit komfortableren Maßparametern:
h=cyDIB;
b=cxDIB;
for (i=0;i0){ //blue
//if (lpBits[(cyDIB-1-j)*(q*cxDIB+to4)+(q*i)+1]UpdateAllViews(NULL);

AfxMessageBox(„rot ok?“);
}