如何将 PNG 转换为 1 位 BMP

How to convert a PNG to 1-bit BMP

因此,我试图了解 PNG 到 BMP 的转换实际上是如何发生的。我使用在线工具创建了以下 8x8 像素的 PNG:

然后我在 OSX 终端中使用 ImageMagik 工具执行了转换:

$ convert -monochrome pic.png pic.bmp

之后,我对图像进行了 hexdump:

$ 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

所以,显然我们有一个 BMP header 从 0x00 - 0x8C。然后我们有白色像素的 FF 和黑色像素的 00。这一切都说得通,但输出的结构却并非如此。到目前为止,似乎有一个3比1的比例。每个像素 3 个字节。我假设这意味着黑色、白色、no-color?

我需要完全理解为什么每个像素有 3 个字节而不是 2 个字节。理想情况下,我希望每个像素使用二进制 1 或 0。有没有办法做到这一点?如果没有,有人可以解释字节的布局吗?具体来说:为什么 3 个 00 位于 0x132 - 0x134 而不是最开始?

谢谢

我不确定这将回答哪个问题,但来自 Usage docs

IM can not produce BMP's at depth levels other than 8. However you can use NetPBM image processing set to do the final conversion to other depth levels (This needs at least a Q16 version of IM)...

所以如果我们利用 NetPBM

$ convert pic.png -depth 1  ppm:- | hexdump

给出(注意值是 0 和 1,但你仍然有一个 RGB 通道)

0000000 50 36 0a 38 20 38 0a 31 0a 00 00 00 01 01 01 01
0000010 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
*
00000c0 01 01 01 01 01 01 01 01 01                     
00000c9

所以我的解决方法很简单

$ convert pic.png -depth 1  ppm:- | pnmdepth 1 | ppm2bmp > pic.bmp

在 Fedora 27 上,该命令是:

$ convert pic.png -depth 1  ppm:- | pnmdepth 1 | ppmtobmp > pic.bmp

你需要:

$  dnf install netpbm-progs

Imagemagick 实际上支持 1 位 BMP,如果使用 BMP3 或 BMP2 格式,但不支持 BMP4,它只是 BMP。所以如果你想要每个通道 1 位深度,那么做

输入:

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

如果您想要整个图像(即二进制)的 1 位深度,则执行

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

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