PNG IDAT规范

3
我正在查阅W3 PNG规范(从头开始创建PNG库),现在我终于找到了如何创建一个绿色的1x1图像的方法。现在我正在尝试创建一个更大的混合红,绿和蓝颜色像素的图像,比如4x4的图像。不幸的是,我得到了所有的像素混合在一起,其中一些是黑色或粉红色。
细节:
- Signature: OK - IHDR: OK - Width: 4 - Height: 4 - Bit depth: 8 - Color: 2 - Filter: 0 - Compression: 0 - Interlace: 0 - IDATA: 4个块* - IEND: OK
*IDATA块:
- 4字节长度:Zlib压缩后数据的字节数 - 4个1字节类型:IDAT - X字节数据:4个4字节无符号整数,依次Zlib压缩,网络字节序
- 蓝色为255** - 绿色为65280** - 红色为16711680**
- 4字节crc:OK
**按位结果为:
alpha<<24 | red<<16 | green<<8 | blue

在alpha、蓝色、绿色和红色取值范围从0到255的情况下,这有什么问题吗?


这个问题被同时发布到DSP上,所以我把我的回答也复制到了那里。 - Glenn Randers-Pehrson
1个回答

8
PNG像素的顺序是RGBA,而不是ARGB,因此您需要编写:
alpha | red<<24 | green << 16 | blue <<8

但是你正在编写颜色类型2,因此每个像素应该是3个字节而不是四个;你不能像你所做的那样将它们编码为4字节整数。因此,要么将颜色类型更改为6,要么切换到将每个样本作为单独的字节进行编写。此外,您需要在每行开头添加一个过滤字节。对于您来说,零将起作用。因此,在您的示例4x4 RGB图像中,每行需要写入13个字节。
0 R G B R G B R G B R G B
0 R G B R G B R G B R G B
0 R G B R G B R G B R G B
0 R G B R G B R G B R G B

然后将所有行字节连接成一个字节流并进行zlib压缩。它可以全部放在一个IDAT块中。如果您需要编写较小的IDAT块,则必须先对图像进行zlib压缩,然后将zlib输出拆分为连续IDAT块中放置的片段。


很好的解释。我会立刻尝试。关于行……我猜它们将根据图像宽度呈现,对吗?所以我只需要一个接一个地写这些13字节组。 - Roberto Decurnex
1
是的,只需将您的行字节连接成一个长流并将其发送到zlib即可。 - Glenn Randers-Pehrson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接