How to convert a PNG to 1-bit BMP

bmpimageimagemagickpng

So, I'm trying to understand how PNG to BMP conversion actually takes place. I created the following 8×8 pixel PNG using a tool online:

enter image description here

I then performed a conversion using the ImageMagik tool in OSX terminal:

$ convert -monochrome pic.png pic.bmp

Afterwards, I did a hexdump of the image:

$ hexdump -C pic.bmp
00000000 42 4d 4a 01 00 00 00 00 00 00 8a 00 00 00 7c 00 |BMJ...........|.|
00000010 00 00 08 00 00 00 08 00 00 00 01 00 18 00 00 00 |................|
00000020 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 ff 00 00 ff 00 00 ff 00 |................|
00000040 00 00 00 00 00 ff 42 47 52 73 8f c2 f5 28 51 b8 |......BGRs...(Q.|
00000050 1e 15 1e 85 eb 01 33 33 33 13 66 66 66 26 66 66 |......333.fff&ff|
00000060 66 06 99 99 99 09 3d 0a d7 03 28 5c 8f 32 00 00 |f.....=...(\.2..|
00000070 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 |................|
00000080 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff ff |................|
00000090 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000130 ff ff 00 00 00 ff ff ff ff ff ff ff ff ff ff ff |................|
00000140 ff ff ff ff ff ff ff ff ff ff |..........|
0000014a

So, obviously we have a BMP header from 0x00 – 0x8C. Then we have FF for white pixels and 00 for black. That all makes sense, but the structure of the output doesn't. So far, it seems that there is a 3 to 1 ratio. 3 bytes per pixel. I'm assuming this means black, white, no-color?

I need to fully understand why there are 3 bytes per pixel instead of 2. Ideally, I would like a binary 1 or 0 for each pixel instead. Is there a way to do this? And if not, can someone please explain the layout of bytes? Specifically: Why are the 3 00s at 0x132 – 0x134 and not the very beginning?

Thanks

Best Answer

Imagemagick, in fact, does support 1-bit BMP, if using either BMP3 or BMP2 formats, but not BMP4 which is just BMP. So if you want 1-bit depth per channel, then do

Input:

enter image description here

convert image.png -depth 1 BMP3:result.bmp

enter image description here

If you want a 1-bit depth for the whole image (i.e. binary), then do

convert image.png -depth 1 -type bilevel BMP3:result2.bmp

enter image description here

Or

convert image.png -depth 1 -threshold 50% BMP3:result3.bmp

enter image description here