progstudent
asked on
Looking at the guts of a bitmap
My question concerns the opening and reading of a bitmap file for the purpose of examining the data contained within the file itself. I do not wish to send the bitmap to any device.
Let’s take a bitmap, for example, 10 pixels in width by 10 pixels in length. The image information is 1 bit per pixel. First, I need to open the bitmap -- I would like to use CreateFile () to get a handle to a file. Then I would like to read information from the file using ReadFile (). Bit by bit, I want to fill a character array with ASCII ones and zeros to later print to the screen or a printer and examine. I want to see something like the following as a result:
0000000000
0111111100
0000100000
0111111100
0000000000
0111110100
0000000000
0101111110
0000000000
0000000000
I am new to C++/Windows programming (a student as you can tell from the moniker) and I am not familiar with the CreateFile () and ReadFile () functions. Example code, therefore, is a must. If you have a better way of working a solution to this problem, I am very much open to your suggestions! I am forever indebted to the woman or man who answers my question!
Let’s take a bitmap, for example, 10 pixels in width by 10 pixels in length. The image information is 1 bit per pixel. First, I need to open the bitmap -- I would like to use CreateFile () to get a handle to a file. Then I would like to read information from the file using ReadFile (). Bit by bit, I want to fill a character array with ASCII ones and zeros to later print to the screen or a printer and examine. I want to see something like the following as a result:
0000000000
0111111100
0000100000
0111111100
0000000000
0111110100
0000000000
0101111110
0000000000
0000000000
I am new to C++/Windows programming (a student as you can tell from the moniker) and I am not familiar with the CreateFile () and ReadFile () functions. Example code, therefore, is a must. If you have a better way of working a solution to this problem, I am very much open to your suggestions! I am forever indebted to the woman or man who answers my question!
ASKER
Thank you so much for such a prompt reply!
First, I did not mean to suggest that this program was for any school related project -- It is not. I would never ask for the solution for any school material! This program is for my own project at home with a friend.
Second, I was hoping for clarification on the usage of the function ReadFile() specifically because I am trying to familiarize myself with it's use. I know the basic libaray routines for C++, I took a course that covered the basics. I am trying work with file handles now, using the 32 bit libaray routines for Windows 95 programming.
First, I did not mean to suggest that this program was for any school related project -- It is not. I would never ask for the solution for any school material! This program is for my own project at home with a friend.
Second, I was hoping for clarification on the usage of the function ReadFile() specifically because I am trying to familiarize myself with it's use. I know the basic libaray routines for C++, I took a course that covered the basics. I am trying work with file handles now, using the 32 bit libaray routines for Windows 95 programming.
ASKER
Thank you so much for such a prompt reply!
First, I did not mean to suggest that this program was for any school related project -- It is not. I would never ask for the solution for any school material! This program is for my own project at home with a friend.
Second, I was hoping for clarification on the usage of the function ReadFile() specifically because I am trying to familiarize myself with it's use. I know the basic libaray routines for C++, I took a course that covered the basics. I am trying work with file handles now, using the 32 bit libaray routines for Windows 95 programming.
The part that is tripping me up, actually is determining the actual ones and zeros of the bitmap. I have successfully opened and read files using the functions mentioned in my question, but for characters and integers and the like. How do you determine the value of a single bit, rather than a byte?
Further clarification would be most helpful!
First, I did not mean to suggest that this program was for any school related project -- It is not. I would never ask for the solution for any school material! This program is for my own project at home with a friend.
Second, I was hoping for clarification on the usage of the function ReadFile() specifically because I am trying to familiarize myself with it's use. I know the basic libaray routines for C++, I took a course that covered the basics. I am trying work with file handles now, using the 32 bit libaray routines for Windows 95 programming.
The part that is tripping me up, actually is determining the actual ones and zeros of the bitmap. I have successfully opened and read files using the functions mentioned in my question, but for characters and integers and the like. How do you determine the value of a single bit, rather than a byte?
Further clarification would be most helpful!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hooray!! We tried out your code, and IT WORKS!! To see it in action initially, we tested it out as follows:
int main()
{
char test;
test = '5';
// int test = 5;
for(int i = 8 ;i >0;i--)
{
if ( GetBit( test, (i-1) ) )
cout << "1";
else
cout << "0";
}
return 0;
}
You are a GENIUS!! OK So far so good... You get an A. But before we accept this answer, we were hoping to squeeze a bit more information out of you! Heck, I'll even throw in 30 exra points if you answer this next part. (If you dont answer, I'll give you the A anyways, since it answered what we really needed about single bits.)
The next part of this question is about the bitmap. We are using Paint to scribble up some single bit, black and white simple-as-you-can-get bitmaps, 25 x 50 pixels in size. Now we understand there is a header with information about the file in here somewhere, but we are not sure if it is at the beginning of the file, ar at the end. Also, how large is the header? Is it a word in size? I also understand that the actual bits are read from the end of the file forward, how might I gain access to that info and get it read in the logical, left-to-right-top-to-botto m-as-you-s ee-it sequence? Do I need to determine a pointer to the data stream from the header itself, or does it begin immediately following the header? Maybe the header is at the front of the file, and the data stream begins at the end and works its way forward?
We just want to convert this bitmap to view as ascii ones and zeros so that we can examine the data contained in the bitmap. later, as we read more about bitmaps and palettes, we will attempt to get more complex with our analysis, but we are having a heck of a time just doing the single bit job! Any advice will be helpful! And thanks again to psdavis, and especially to forge!
int main()
{
char test;
test = '5';
// int test = 5;
for(int i = 8 ;i >0;i--)
{
if ( GetBit( test, (i-1) ) )
cout << "1";
else
cout << "0";
}
return 0;
}
You are a GENIUS!! OK So far so good... You get an A. But before we accept this answer, we were hoping to squeeze a bit more information out of you! Heck, I'll even throw in 30 exra points if you answer this next part. (If you dont answer, I'll give you the A anyways, since it answered what we really needed about single bits.)
The next part of this question is about the bitmap. We are using Paint to scribble up some single bit, black and white simple-as-you-can-get bitmaps, 25 x 50 pixels in size. Now we understand there is a header with information about the file in here somewhere, but we are not sure if it is at the beginning of the file, ar at the end. Also, how large is the header? Is it a word in size? I also understand that the actual bits are read from the end of the file forward, how might I gain access to that info and get it read in the logical, left-to-right-top-to-botto
We just want to convert this bitmap to view as ascii ones and zeros so that we can examine the data contained in the bitmap. later, as we read more about bitmaps and palettes, we will attempt to get more complex with our analysis, but we are having a heck of a time just doing the single bit job! Any advice will be helpful! And thanks again to psdavis, and especially to forge!
ASKER
Adjusted points to 120
Sorry for this late reply, i've been quite busy with school (first week :)).
About the .BMP format: you can find it on the internet, with a little work. I had found it for you and can send you the URL but i dont have the time at the moment.
The header is at the beginning, that's all i know. I believe it is 128 bytes in length. Then follows the palette, which has 2 entries in your case (2 color bitmap). Then follows the bitmap in windows style: the pixel at the top left of your screen is the last pixel in the bitmap. So what you do is you read the entire bitmap in an array ( unsigned char Buffer[25*50/8]; )
and then you write a 'GetPixel' routine to get you the n'th pixel:
bool GetPixel(int n, char * buffer, int imagesizeinbytes) {
return GetBit( buffer[imagesizeinbytes-n/ 8], 8-n);
}
Or something like that. The first part (buffer[...]) gets the right byte (but is scanning backwards to correct for the stupid way windows saves BMP files) and calls the GetBit routine to get the right bit. Again, get the bit backwards: start counting at the highest bit.
You might be a bit or byte off here but i just wrote this from scratch in a big hurry coz i got class right now :)
Let me know if you can't figure anything out.
Greetz.
About the .BMP format: you can find it on the internet, with a little work. I had found it for you and can send you the URL but i dont have the time at the moment.
The header is at the beginning, that's all i know. I believe it is 128 bytes in length. Then follows the palette, which has 2 entries in your case (2 color bitmap). Then follows the bitmap in windows style: the pixel at the top left of your screen is the last pixel in the bitmap. So what you do is you read the entire bitmap in an array ( unsigned char Buffer[25*50/8]; )
and then you write a 'GetPixel' routine to get you the n'th pixel:
bool GetPixel(int n, char * buffer, int imagesizeinbytes) {
return GetBit( buffer[imagesizeinbytes-n/
}
Or something like that. The first part (buffer[...]) gets the right byte (but is scanning backwards to correct for the stupid way windows saves BMP files) and calls the GetBit routine to get the right bit. Again, get the bit backwards: start counting at the highest bit.
You might be a bit or byte off here but i just wrote this from scratch in a big hurry coz i got class right now :)
Let me know if you can't figure anything out.
Greetz.
ASKER
forge,
Follwing is the header information i was asking about. i found it on the internet as you suggested
typedef struct {
/*01*/ WORD bfType; // file type == 'BM'
/*02*/ DWORD bfSize; // size of file in bytes
/*03*/ WORD bfReserved1; // reserved
/*04*/ WORD bfReserved2; // reserved
/*05*/ DWORD bfOffBits; // byte offset where image begins
} BMP_FILEHEADER;
typedef struct {
/*06*/ DWORD biSize; // size of this header, 40 bytes
/*07*/ DWORD biWidth; // image width in pixels
/*08*/ DWORD biHeight; // image height in pixels
/*09*/ WORD biPlanes; // number of image planes (always one)
/*10*/ WORD biBitCount; // bits per pixel, 1,4,8 or 24
/*11*/ DWORD biCompression; // compression type
/*12*/ DWORD biSizeImage; // compressed size
/*13*/ DWORD biXPelsMeter; // x pixels per meter
/*14*/ DWORD biYPelsMeter; // y pixels per meter
/*15*/ DWORD biClrUsed; // number of colors in map
/*16*/ DWORD biClrImportant; // number of important colors
} BMP_INFOHEADER;
the bitmap information directly follows the file information, which begins at the the firstmost byte of the file. We are now able to access the image data at the offset (bfOffBits) and examine the info using your code for single bit editing!
Follwing is the header information i was asking about. i found it on the internet as you suggested
typedef struct {
/*01*/ WORD bfType; // file type == 'BM'
/*02*/ DWORD bfSize; // size of file in bytes
/*03*/ WORD bfReserved1; // reserved
/*04*/ WORD bfReserved2; // reserved
/*05*/ DWORD bfOffBits; // byte offset where image begins
} BMP_FILEHEADER;
typedef struct {
/*06*/ DWORD biSize; // size of this header, 40 bytes
/*07*/ DWORD biWidth; // image width in pixels
/*08*/ DWORD biHeight; // image height in pixels
/*09*/ WORD biPlanes; // number of image planes (always one)
/*10*/ WORD biBitCount; // bits per pixel, 1,4,8 or 24
/*11*/ DWORD biCompression; // compression type
/*12*/ DWORD biSizeImage; // compressed size
/*13*/ DWORD biXPelsMeter; // x pixels per meter
/*14*/ DWORD biYPelsMeter; // y pixels per meter
/*15*/ DWORD biClrUsed; // number of colors in map
/*16*/ DWORD biClrImportant; // number of important colors
} BMP_INFOHEADER;
the bitmap information directly follows the file information, which begins at the the firstmost byte of the file. We are now able to access the image data at the offset (bfOffBits) and examine the info using your code for single bit editing!
There are a multitude of ways to open up a file. It really depends on your programming environment. If you are a beginning C student, you may want to familiarize yourself with the 'standard' library functions available to all C operating system environments. The CreateFile function is a Win32 function that is specifically a Microsoft style function. A more generic counterpart is the fopen library command. Here's the sample code for it. It is drastically easier to use than the CreateFile/ReadFile counterparts.
/* FOPEN.C: This program opens files named "data"
* and "data2".It uses fclose to close "data" and
* _fcloseall to close all remaining files.
*/
#include <stdio.h>
FILE *stream, *stream2;
void main( void )
{
int numclosed;
/* Open for read (will fail if file "data" does not exist) */
if( (stream = fopen( "data", "r" )) == NULL )
printf( "The file 'data' was not opened\n" );
else
printf( "The file 'data' was opened\n" );
/* Open for write */
if( (stream2 = fopen( "data2", "w+" )) == NULL )
printf( "The file 'data2' was not opened\n" );
else
printf( "The file 'data2' was opened\n" );
/* Close stream */
if( fclose( stream ) )
printf( "The file 'data' was not closed\n" );
/* All other files are closed: */
numclosed = _fcloseall( );
printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
Take a look at any standard documentation for more info on it. Instead of ReadFile, use the standard fread.
Now for your quazi-bitmap. Use the fread function something like this...
fread( szCharBuffer, sizeof( char ), 10, fInputFile );
Good luck!
Phillip