Loading Bitmaps from files
First off, thanks to everyone whos helped me out with my game. Ive been hitting a lot of problems lately, but I think that I may have been doing something fundamentally wrong all along. When you want to read in a bitmap from a file, what struct(s) should you read in? Currently, this is what I''m doing...
BITMAP bmp;
unsigned long memsize;
ifstream in("my.bmp", ios::binary / ios::nocreate);
in.read((char*) &bmp, sizeof(BITMAP));
memsize = bmp.bmWidthBytes * bmp.bmHeight;
bmp.bmBits = (LPVOID) new char[memsize];
in.read((char*) &bmp.bmBits, memsize);
Unfortunaly, the value of bmp.bmWidthBytes * bmp.bmHeight is so large, that an unsigned long cannot hold it... this has got to mean that I am incorrectly reading in the bitmap. I have gone through my Programming Windows 95 book (hey, it was $4 because the 98 one just came out) =) and it has TONS about working with bitmaps, but it doesnt have dick about reading them in from a file... apparently the jackass that wrote it never even thought about game programmers. So, my question to you all is this: What is the file format of your average bitmap file made my paint/photoshop so that I can read it into my program?
Thanks!
There is no spoon.
Fortunately, you can use an API function to load an image. it''s called LoadImage.
just call the function like:
HBITMAP hbm = LoadImage( NULL, "file.bmp", LR_LOADFROMFILE / LR_CREATEDIBSECTION );
or something like that. i can''t remember the actual syntax, and i don''t have my api ref at this computer.
if you want to read a bitmap from a WAD-type file, it''s a little harder, but there is some code in a message from a few months ago that would be of good use. if i remember right, you just load the file contents verbatim into memory and pass that memory to load image. search for it in "general" section.
crazy166
some people think i'm crazy, some people know it
just call the function like:
HBITMAP hbm = LoadImage( NULL, "file.bmp", LR_LOADFROMFILE / LR_CREATEDIBSECTION );
or something like that. i can''t remember the actual syntax, and i don''t have my api ref at this computer.
if you want to read a bitmap from a WAD-type file, it''s a little harder, but there is some code in a message from a few months ago that would be of good use. if i remember right, you just load the file contents verbatim into memory and pass that memory to load image. search for it in "general" section.
crazy166
some people think i'm crazy, some people know it
I've just spent the last 5 hours rewriting my bitmap loader 3 times. Anyways, I think Andre LaMothe's method is the best for loading bitmaps:
The bitmaps on the disk aren't the same format as the BITMAP structure. Here is an good structure to use (again ripped from LaMothe)
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER bitmapinfoheader;
PALETTENTRY palette[256];
UCHAR * buffer;
} BITMAP_FILE, *BITMAP_FILE_PTR;
Here are the general steps to load a bitmap
first read the BITMAPFILEHEADER struct, then read in the BITMAPINFOHEADER struct.
Then check to see if it is in fact a bitmap (first two bytes are 4D42 of BITMAPFILEHEADER, I believe).
Then check to see if it is 8 bits and has a palette. If it is, read in the palette and reserve the the RGBQUADS (in BGRF format instead of RGBF).
Here comes the tricky part. You have to seek to the end of the file then backtrack to get the start of the image. This is the only way to make sure that you get the right data. something like the following is needed:
in.seekg(-bitmapinfoheader.biSizeImage, ios::end);
Get some space for the image using the new or malloc() functions.
Now load the picture data into your char *.
If it is 24 bit, then you also have to reverse the BGR into RGB and convert it to 16 bit if needed.
Next you have to reverse the lines of the bitmap because they are stored upside down for some reason.
I hope this helps.
Email me at dethsled@uberhacker.org if you want the full code.
Note: This info came from LaMothe's Windows Game Programming For Dummies.
-Dethsled
Edited by - dethsled on June 22, 2000 12:43:33 AM
The bitmaps on the disk aren't the same format as the BITMAP structure. Here is an good structure to use (again ripped from LaMothe)
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER bitmapinfoheader;
PALETTENTRY palette[256];
UCHAR * buffer;
} BITMAP_FILE, *BITMAP_FILE_PTR;
Here are the general steps to load a bitmap
first read the BITMAPFILEHEADER struct, then read in the BITMAPINFOHEADER struct.
Then check to see if it is in fact a bitmap (first two bytes are 4D42 of BITMAPFILEHEADER, I believe).
Then check to see if it is 8 bits and has a palette. If it is, read in the palette and reserve the the RGBQUADS (in BGRF format instead of RGBF).
Here comes the tricky part. You have to seek to the end of the file then backtrack to get the start of the image. This is the only way to make sure that you get the right data. something like the following is needed:
in.seekg(-bitmapinfoheader.biSizeImage, ios::end);
Get some space for the image using the new or malloc() functions.
Now load the picture data into your char *.
If it is 24 bit, then you also have to reverse the BGR into RGB and convert it to 16 bit if needed.
Next you have to reverse the lines of the bitmap because they are stored upside down for some reason.
I hope this helps.
Email me at dethsled@uberhacker.org if you want the full code.
Note: This info came from LaMothe's Windows Game Programming For Dummies.
-Dethsled
Edited by - dethsled on June 22, 2000 12:43:33 AM
quote:
You have to seek to the end of the file then backtrack to get the start of the image
That sounds a little dangerous, some programs write version information to the ends of files; the last dword of the BITMAPFILEHEADER struct has an offset to the data.You should probably use that to blindly get to the data section.
Also, some bitmaps use run-length encoding for compression (and other things too), check out some of the bitmap format specs on wotsit.org for a whole lot of information.
----------
meh
----------meh
Holy shit this is complicated... I like the sound of LoadImage() much, much, better... but I doubt it will work for removing the bitmap from the .wad. So how can I check the first 2 bytes... read in 2 chars to a buffer? How do I check if it has a palette and how can you tell if it is 8, 16, 24, or 32 bits? Thats a lot of questions!
There is no spoon.
This is the EASY part! (just trying to scare you...not working, huh?).
Do what dethsled said, compare the byType field of the BITMAPFILEHEADER against 0x4D42 (0x4D42 == ''BM'')
If the biBitCount field of the BITMAPINFOHEADER is 8 or less, then it has a palette, this is called an indexed file.The palette is an array of rgb information (actually, in a bitmap, its in bgr format, also, every fourth byte is a 0.Bitmaps are also stored upside down.), and the data section is an array of indicies into the palette.
the biBitCount field of the BITMAPINFOHEADER says what bit depth its in, 8 for 8 bit, etc.
Good luck
----------
meh
quote:
how can I check the first 2 bytes
Do what dethsled said, compare the byType field of the BITMAPFILEHEADER against 0x4D42 (0x4D42 == ''BM'')
quote:
How do I check if it has a palette
If the biBitCount field of the BITMAPINFOHEADER is 8 or less, then it has a palette, this is called an indexed file.The palette is an array of rgb information (actually, in a bitmap, its in bgr format, also, every fourth byte is a 0.Bitmaps are also stored upside down.), and the data section is an array of indicies into the palette.
quote:
how can you tell if it is 8, 16, 24, or 32 bits?
the biBitCount field of the BITMAPINFOHEADER says what bit depth its in, 8 for 8 bit, etc.
Good luck
----------
meh
----------meh
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement