Sign in to follow this  

Reading bmps - help!

This topic is 4658 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well hello, this is my first post... First thing I'm not a newbie to programming, but only recently I've started learning it more seriously and doing programs that are more than simply "wow that's cool now get away". As of now I know C. So my question is: When you read a bitamp file whose widths and heights are not divided by 4, it comes out all streched or just gibberish. I've tried reading the file and then filling rows and columns with pixels I've defined as opaque until it's divided by four, but it doesn't do much change. I've tried a few other things that did absolutly nothing. So, how do I do it? Thanks ahead, and may your compiler never show errors. /// edit: I posted in the beginer forum and it somehow ended up here O-o If you can pass it I'll be grateful.

Share this post


Link to post
Share on other sites
In a Bitmap if the width multipied by bytes per pixel isn't an even number then there is an extra byte that doesn't do anything at the end of every line or row of pixels.

Share this post


Link to post
Share on other sites
I had a similar problem with the WORD padding. Here is my code, it took a while to get it right. Just keep paying with it, and you will eventually get it:


//this is a 24bpp bitmap, so I get the actual pixel width
byteWidth := header.gWdith * 3;
padWidth := byteWidth;

//i increase the size until it is on a 4 byte boundry
while(padWidth mod 4 <> 0) do
padWidth := padWidth + 1;

//this is the actual image size with no padding
diff := header.gHeight * byteWidth;
//this just sets an array to be the size of the actual image
SetLength(imageData, diff);
SetLength(tempImageData, byteWidth + 1);
header.gSize := diff;

//I set the offset to be the difference between the padded width and the unpadded width
offset := padWidth - byteWidth;

saveCursor := screen.Cursor;
screen.Cursor := crHourGlass;

//loop for every pixel of the image
for index := 0 to (diff - 1) do
begin
//if it is at then end of a line (before the padding), then skip past the padding
if (((index+1) mod (byteWidth)) = 0) then
begin
seek(myFile, filepos(myFile) + (offset));
end;
//read in the byte
BlockRead(myFile, imageData[index], 1);

end;


Sorry that it isn't in C++, but I added in some comments. It shouldn't be hard to convert to C++.
[/source]

Share this post


Link to post
Share on other sites
This is the so-called "stride" of the bitmap. It means that a scanline in the bitmap must always be a multiple of 4 bytes. When you create a DIB section in Windows, the memory buffer also has this stride. In other words, when you use the DIB routines in Windows itself, you can just load directly without worrying about the padding.


scanlinelength = (width * bitsperpixel) >> 3;
stride = (scanlinelength + 3) & ~3;
padding = stride - scanlinelength;

Share this post


Link to post
Share on other sites
Aha,

This probably explains why I was having some trouble some time ago when I was working with 24 bit bitmaps. (r (byte), g (byte) b (byte) )

At certain resolutions it worked fine and at others it didn't.

I tried out 32bt (a (byte), r (byte), g (byte) b (byte) ) and that worked because, clearly, it's 4 bytes per pixel.

That's interesting to know.

Sorry for going a bit off-track there "Krynnish Conspiracy"

Matt

Share this post


Link to post
Share on other sites
Sorry I haven't replied yet, I was busy, but here I am.

Thank you for your replies... I used what SuperNerd said and now it works great (:

Thanks again, I'll be back if I have more question or if I think I know enough to benefit other people.

Until then, farewell, and may none of your programs ever crash!

Share this post


Link to post
Share on other sites
Quote:
Original post by Krynnish Conspiracy
I used what SuperNerd said and now it works great (:


Don't. It's not entirely correct. He assumes the number of bytes must be even (a multiple of two). Rather, it should be a multiple of four (as I posted above).

Share this post


Link to post
Share on other sites

This topic is 4658 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this