Thread: reading .bmp

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    62

    reading .bmp

    Hello!
    I try to read the data of a .bmp file. I'm not sure how to do it. I found some instructions in some other forum and I have completed a part of it:

    Code:
    HANDLE bmp;
    DWORD size;
    DWORD error;
    DWORD byte_count;
    LPVOID data[10000];
    
    int main()
    {
    	bmp=CreateFile("test.bmp", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	size=GetFileSize(bmp, NULL);
    	ReadFile(bmp, data, size, &byte_count, NULL);
    	CloseHandle(bmp);
    }
    I have checked it and it seems that this part works.

    The instructions i found say:
    "and then just cast a pointer to the buffer to a BITMAPFILEHEADER and go from there."

    I don't understand what should I do next.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    BITMAPFILEHEADER is a struct which defines the header contents of a BMP file. It's telling you to do something like this:

    Code:
    // after reading the contents of the file into the buffer...
    BITMAPFILEHEADER *bmpHeader = (BITMAPFILEHEADER *)data;
    At that point you can access the header through data->
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Read up on BITMAPFILEHEADER then.

    This struct contains little useful info, though, just the offset of the pixel data. The next data structure that follows it contains more useful info.

    As to the cast, I'd suppose it would look something like:

    Code:
    BITMAPFILEHEADER* file_header = reinterpret_cast<BITMAPFILEHEADER*>(data);
    (Don't know what's this array of LPVOID's you are reading data into, might rather use a char array.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Aug 2006
    Posts
    62
    Now I managed to access the BITMAPFILEHEADER structure. How can I access other parts of the bitmap? Do I have to somehow use the offset to the data I get from the BITMAPFILEHEADER?

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    62
    I solved the problem. I changed the method a bit but that really doesn't change anything.
    I post the code in case someone other has the same problem. Google often gives me links to forums with unanswered questions and I hate it.

    This is an example on 256 color bitmaps. 24-bit should be a bit different. Here's the code anyway:

    Code:
    FILE *bmp;
    FILE *data;
    BITMAPFILEHEADER bmpHeader;
    BITMAPINFOHEADER bmpInfo;
    RGBQUAD rgb[256];
    BYTE pixel[100000];
    int pixel_count;
    int add1, add2;
    
    int main()
    {
    	bmp=fopen("test.bmp", "rb");
    	fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, bmp);
    	fread(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, bmp);
    
    	pixel_count=bmpInfo.biHeight*bmpInfo.biWidth;
    	add1=bmpInfo.biWidth%4;		//The bytes are situated in the line as arrays with a size of 4 multiples. If there are less than a 4 multiple bytes, zeros are added to the end.
    	add2=bmpInfo.biHeight*add1;//As there are some zeros in included, I have to read some more bytes that just the pixel count. I calculate how much more.	
    
    	fread(&rgb, sizeof(RGBQUAD), 256, bmp);	// Reading all 256 colors
    
    	fseek(bmp, bmpHeader.bfOffBits, SEEK_SET);    //Just in case I'm somehow in the wrong position, although the pixel data should follow anyway.
    	fread(&pixel,  sizeof(char), pixel_count+add2, bmp);
    
    	fclose(bmp);
    
            //Writing the data to the text file
    	data=fopen("data.txt", "w");
    
    	for(int i=0; i<bmpInfo.biHeight; i++)
    	{
    		for(int j=0; j<bmpInfo.biWidth+add1; j++)
    		{
    			if(j<bmpInfo.biWidth) fprintf(data, "%.2x%.2x%.2x\n", rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbRed, rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbGreen, rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbBlue);
    //The bitmap data gives me the number of its color in the color array, so I print the colors instead of that quite useless number. It's a bit complicated as the bitmap data starts from the lower right corner and I would like it start from the upper corner.
    		}
    		fprintf(data, "\n");
    	}
    
    	fclose(data);
    
    }

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    137
    Quote Originally Posted by fighter92 View Post
    I post the code in case someone other has the same problem. Google often gives me links to forums with unanswered questions and I hate it.
    See Google Groups not Google.
    The right code has been posted about 1500 times for 20 years on Win32 api newsgroups.
    Also in MSDN of course.

  7. #7
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    You could also create your own portable c++ classes using the format specifications on wikipedia. It's not hard, but it's probably unnecessary.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  8. #8
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Quote Originally Posted by fighter92 View Post
    I solved the problem. I changed the method a bit but that really doesn't change anything.
    I post the code in case someone other has the same problem. Google often gives me links to forums with unanswered questions and I hate it.

    This is an example on 256 color bitmaps. 24-bit should be a bit different. Here's the code anyway:

    Code:
    FILE *bmp;
    FILE *data;
    BITMAPFILEHEADER bmpHeader;
    BITMAPINFOHEADER bmpInfo;
    RGBQUAD rgb[256];
    BYTE pixel[100000];
    int pixel_count;
    int add1, add2;
    
    int main()
    {
    	bmp=fopen("test.bmp", "rb");
    	fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, bmp);
    	fread(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, bmp);
    
    	pixel_count=bmpInfo.biHeight*bmpInfo.biWidth;
    	add1=bmpInfo.biWidth%4;		//The bytes are situated in the line as arrays with a size of 4 multiples. If there are less than a 4 multiple bytes, zeros are added to the end.
    	add2=bmpInfo.biHeight*add1;//As there are some zeros in included, I have to read some more bytes that just the pixel count. I calculate how much more.	
    
    	fread(&rgb, sizeof(RGBQUAD), 256, bmp);	// Reading all 256 colors
    
    	fseek(bmp, bmpHeader.bfOffBits, SEEK_SET);    //Just in case I'm somehow in the wrong position, although the pixel data should follow anyway.
    	fread(&pixel,  sizeof(char), pixel_count+add2, bmp);
    
    	fclose(bmp);
    
            //Writing the data to the text file
    	data=fopen("data.txt", "w");
    
    	for(int i=0; i<bmpInfo.biHeight; i++)
    	{
    		for(int j=0; j<bmpInfo.biWidth+add1; j++)
    		{
    			if(j<bmpInfo.biWidth) fprintf(data, "%.2x%.2x%.2x\n", rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbRed, rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbGreen, rgb[pixel[(pixel_count+add2-(bmpInfo.biWidth+add)*(i+1))+j]].rgbBlue);
    //The bitmap data gives me the number of its color in the color array, so I print the colors instead of that quite useless number. It's a bit complicated as the bitmap data starts from the lower right corner and I would like it start from the upper corner.
    		}
    		fprintf(data, "\n");
    	}
    
    	fclose(data);
    
    }
    Are you absolutely sure this code works? There is a typo in the above code. I changed the typo to what I thought would probably be the correct variable and ran your code. I compared the output of your code to my test app and there is no similarity. Just to verify that my test app works correctly, I created another BMP using the data the I read in from the original BMP and compared both BMP's with a paint program. Both BMP's were identical. I'd suggest that you go back to the drawing board on the above code. Especially the one statement with the typo's. It's just way to complex and can be reduced to something substantially simpler.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. .jp2 image file to .bmp image file using C language
    By prabs005 in forum C Programming
    Replies: 14
    Last Post: 07-07-2009, 04:02 PM
  2. Replies: 3
    Last Post: 03-05-2009, 03:14 AM
  3. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  4. Replies: 2
    Last Post: 01-28-2008, 03:07 AM
  5. Problem reading 8 bit greyscale images !
    By Clueless@work in forum C Programming
    Replies: 12
    Last Post: 07-01-2007, 11:07 AM