Parsing Bitmap Data

Started by
8 comments, last by VisualB4BigD 21 years, 10 months ago
What I want to do is to properly take a bitmap and stick it in my Packager format. Then I want to read the bitmap out of the file and load it into a picture box. I''m using VB and the FileSystemObject. Any suggestions? Please help I need this really bad. Horny Farmer (Jolly Rancher)
Advertisement
Are you asking for the format of bitmap files?
Format of a BitMap

BITMAP FILE HEADER

First 16 bits = file type = 0100 0010 0100 1101

size of entire file in bytes

next 8 bits = byte0 of size of entire file in bytes
next 8 bits = byte1 of size of entire file in bytes
next 8 bits = byte2 of size of entire file in bytes
next 8 bits = byte3 of size of entire file in bytes

next 32 bits = reserved = all zeros

offset from start of file (in bytes) to where pixel data starts = normally 54 in all my tests

next 8 bits = byte0 of offset
next 8 bits = byte1 of offset
next 8 bits = byte2 of offset
next 8 bits = byte3 of offset

BITMAP INFO HEADER

number of bytes needed by the BITMAP INFO HEADER

next 8 bits = byte0 of bytes needed
next 8 bits = byte1 of bytes needed
next 8 bits = byte2 of bytes needed
next 8 bits = byte3 of bytes needed

width of the bitmap in pixels

next 8 bits = byte0 of width
next 8 bits = byte1 of width
next 8 bits = byte2 of width
next 8 bits = byte3 of width

height of the bitmap in pixels

next 8 bits = byte0 of height
next 8 bits = byte1 of height
next 8 bits = byte2 of height
next 8 bits = byte3 of height

next 8 bits = 0000 0001
next 8 bits = 0000 0000

bits per pixel = usually 24 = 0001 1000 0000 0000

next 8 bits = byte0 of bpp
next 8 bits = byte1 of bpp

type of compression = 0 means uncompressed (dont know about others)

next 8 bits = byte0 of compression
next 8 bits = byte1 of compression
next 8 bits = byte2 of compression
next 8 bits = byte3 of compression

size of image including any padded zeros to make rows DWORD length divisible

next 8 bits = byte0 of size
next 8 bits = byte1 of size
next 8 bits = byte2 of size
next 8 bits = byte3 of size

horizontal resolution of bitmap in pixels per meter = usually => 3780 or 0xC40E

next 8 bits = byte0 of horizontal resolution
next 8 bits = byte1 of horizontal resolution
next 8 bits = byte2 of horizontal resolution
next 8 bits = byte3 of horizontal resolution

vertical resolution of bitmap in pixels per meter = usually => 3780

next 8 bits = byte0 of vertical resolution
next 8 bits = byte1 of vertical resolution
next 8 bits = byte2 of vertical resolution
next 8 bits = byte3 of vertical resolution

next 32 bits = number of colors in the color table actually used by the bitmap. If it is 0 then
the bitmap uses the max number of colors specifed by the bits per pixel above. set to 0
next 32 bits = number of colors that are considered important. What a stupid variable. Set to 0 and all
colors are equally important. Jeez!

PIXEL DATA

24 bits per pixel RGB
IF the number of bytes in a row of pixels (or the number of pixels * 3) is not evenly divisible by 4 then
add bytes of zeros until it is evenly divisible by 4 on each row.
An easier method IMO would be to simply read the file from your packager format and save it to a temp directory, then load the image from there using the LoadPicture subroutine, that would cut down on the reading the bitmap directly from your packaged file. Another method would be to use your own graphics file format and load that directly from your packager file, that would save on learning the bitmap format, which isn''t that difficult to understand, but having your own proprietary format would have its benefits.
What I ended up doing is steping through the bitmap and saving each pixel as a long in my package. After every long value I added a space. Then for every row of the image I added a new line. Works fine, but the size is a major bloat. I don''t care though. It might be inconvient to have users trasfer the package with their level. Just a thought though.

Horny Farmer (Jolly Rancher)
wow.. saving each pixel as a long plus a space?
thats appx 9 bytes per pixel.
if i were you, i''d write an algorithm (or find an api one
that''ll do it for you) that would return the
R, G, and B values of said pixel.
then you could shrink your size to 3 bytes
per pixel and save the file in binary format
instead of ascii.. hell, even storing it
as a hex value would be more efficient than the
long integer. look into the CLng() function..
been a while since i''ve messed with VB, but that
should return a VB hex string.. (ie- &H02)
note: hex isn''t always more efficient than a long
int, but in most cases it is.. i still recommend you
break the color down into RGB values though...
with either of those methods you could implement a form
of RLE compression.. just a thought.

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::

-eldee;another space monkey;[ Forced Evolution Studios ]
I reliezed that size issue. I was just looking for a way to get it to work and it was late. So yeah now I think I will switch it to RGB, I know how to convert it and everything, but I was lazy. What does saving it as binary give me?

Horny Farmer (Jolly Rancher)
Maybe I''m not clear on what you''re doing, but you can simply read in nearly any supported picture type using..


  picX.Picture = LoadPicture("c:\filename.bmp")  
understood. But the problem I was having is the file I need to read the bitmap from is in another file. And when using the FileSystemObject. If you call ReadLine() it reads until it detects the line break character. And with a bitmap those are scattered everywhere. So it really screws things up.

Horny Farmer (Jolly Rancher)
saving in binary mode saves space in your case..
for example, lets say you wanted to store the color
RGB(65,65,65) and you were to do it in ascii..
in ascii you''d have to make a delimiter so you''d know when the
next color was coming-

ascii file:

65 65 65

where space is the delimiter.

in binary, the exact same thing would be:

AAA

3 bytes versus 8.

you can only store up to 256 ''numbers'' in a byte, so what
alot of people do is use two byte chunks for certain things.

for example, i''ve got my own image format (i use many alpha channels)
and before the actual image data i store things like so:

[2][2][1][image data]

(thats'' supposed to be a representation of the byte chunks
in my file.. heh)

the first two are for width and height, the single byte is
for the number of alpha channels, and the image data follows it.
the way i use the two bytes with the width/height is like this:
width = (byte2 * 256) + byte1
height = (byte 4 * 256) + byte3

an example of what this would look like in binary:
@ Ç #
64x128 with 35 alpha channels (thats waaay more than i ever use )

hope this made sense.. binary is your friend

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::

-eldee;another space monkey;[ Forced Evolution Studios ]

This topic is closed to new replies.

Advertisement