Sign in to follow this  
Followers 0
Myicq

BMP to raw - simple bit magic ?

5 posts in this topic

I would like to convert between BMP and RAW bmp files, but seem to stumble at bit on the encoding of the BMP.

What I need is to convert attached BMP file, which is 256 color BMP in 48x48 px. Output should be raw bytes, with the size added in little endian (four first bytes will be 0x30 0x00 0x30 0x00).

I made a small test with first and last pixel containing color 01 (start) and color 254 (end). From this it appears that original BMP is stored "backwards" (end to start) while the raw bytes are stored "forwards" (start to end).

I guess this can be done in a few lines, possibly even directly in memory in a variable. But I do not know exactly how BMP files are stored.

Any help welcomed.

If need be, I can post Delphi code that does the same. I need to convert old software to something new. And preferably be able to go back from RAW to BMP again.

 

bmp_raw.zip


I am just a hobby programmer, and nothing great to publish right now.

Share this post


Link to post
Share on other sites



You can use this code to extract each pixel color: 

and save the result to a file.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi,

the structure of the Bitmap File Format BMP is very easy.

There is a 54 Bytes header which contains the description / properties of the picture, followed by (in your case a color-table) and the raw "Pixel"-Data.

Your RAW Data contains SizeWidth + SizeHeight and the indices to the color-table.

So if you only need to transform 8-BitPerPixel to SizeX-SizeY-RAW the following Script will do the job...

$bmp = FileRead("alt2.bmp")                        ;load File
$width_lowbyte = (StringMid($bmp, 0x13, 1))        ;extract width
$width_highbyte = (StringMid($bmp, 0x14, 1))       ;you only need 2 Bytes of 4 for width in your case
$height_lowbyte = (StringMid($bmp, 0x17, 1))       ;extract height
$height_highbyte = (StringMid($bmp, 0x18, 1))      ;you only need 2 Bytes of 4 for height in your case

$width = Asc($width_lowbyte) + 255 * Asc($width_highbyte);
$height = Asc($height_lowbyte) + 255 * Asc($height_highbyte)

$bmp_size = $width * $height                       ;math...

$data = StringRight($bmp, $bmp_size)               ;cut header and colorpalette

$data_raw = ""                                     ;data ist Bottom-up, so we have to transform...
For $i = $bmp_size - $width + 1 To 1 Step -$width  ;...lines from bottom to top
    $data_raw &= StringMid($data, $i, $width)
Next

FileDelete("alt2.raw")                             ;quick and dirty
FileWrite("alt2.raw", $width_lowbyte & $width_highbyte & $height_lowbyte & $height_highbyte & $data_raw) ;put width and height and pixel together in a file
And preferably be able to go back from RAW to BMP again.

 

If you have a valid color-table (palette) in an existing Bitmap-File, all you have to do is to edit the view bytes of width and height into the header and replace the "Pixel" (from the RAW)

Edited by AndyG
1 person likes this

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

AndyG, THANK you for giving both perfect solution AND explaining background. :thumbsup: This is a 5 star response! I had maybe 80% of the solution myself, but was messing around with binary__ in various combinations, ending up with a text file full of hex characters. To think that the solution was as simple as String() functions is close to embarassing..

I can now do transformations both ways. AND I can understand how the palette works...  For others: it's 1024 bytes: 256 colors á 4 bytes.

So real nice job.

-- EDIT --

it should be noted that there is a typo in above..

The width and heigth are wrong for anything more than 255 pixel, so correct is:

      $width =  Asc($width_lowbyte) + 256 * Asc($width_highbyte);
      $height = Asc($height_lowbyte) + 256 * Asc($height_highbyte)

 

Not 255 as originally put.

Edited by Myicq

I am just a hobby programmer, and nothing great to publish right now.

Share this post


Link to post
Share on other sites

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  
Followers 0