如何从PNG数据流IHDR块的字节计算图片实际宽高?
从PNG数据流提取图片尺寸的计算方法
我正尝试从数据流中提取PNG图片的尺寸,现有数据流起始部分如下:
137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 2 84 0 0 3 74 8 2 0 0 0 195 81 71 33 0 0 0 ... ^ ^ ^ ^ ^ ^
该数据包含以下信息:
- 签名:
137 80 78 71 13 10 26 10 - IHDR块:
- 长度:
0 0 0 13 - 类型:
73 72 68 82 - 数据:
0 0 2 84 0 0 3 74 8 2 0 0 0 - CRC:
195 81 71 33
- 长度:
- 后续为新块起始
图片尺寸信息编码在IHDR块数据部分的前8字节中:
- 宽度对应字节序列:
0 0 2 84,即b'\x00\x00\x02T' - 高度对应字节序列:
0 0 3 74,即b'\x00\x00\x03J'
已知图片实际宽度为596 px、高度为842 px,计算逻辑如下:
PNG规范中,图片的宽高以**大端字节序(Big-Endian)**存储为32位无符号整数,转换时需按高位到低位的顺序计算:
手动计算方式
- 宽度计算:将4个字节分别乘以2的24、16、8、0次方后求和
0 * 2^24 + 0 * 2^16 + 2 * 2^8 + 84 = 0 + 0 + 512 + 84 = 596 - 高度计算:同理
0 * 2^24 + 0 * 2^16 + 3 * 2^8 + 74 = 0 + 0 + 768 + 74 = 842
Python代码实现
使用Python内置的struct模块可快速完成转换,>I表示按大端字节序解析无符号32位整数:
import struct # 从数据流中提取的宽度字节 width_bytes = b'\x00\x00\x02T' width = struct.unpack('>I', width_bytes)[0] print(width) # 输出:596 # 从数据流中提取的高度字节 height_bytes = b'\x00\x00\x03J' height = struct.unpack('>I', height_bytes)[0] print(height) # 输出:842
如果需要手动计算,也可以直接操作字节列表:
# 宽度字节列表 width_bytes = [0, 0, 2, 84] width = width_bytes[0] * 2**24 + width_bytes[1] * 2**16 + width_bytes[2] * 2**8 + width_bytes[3] print(width) # 596 # 高度字节列表 height_bytes = [0, 0, 3, 74] height = height_bytes[0] * 2**24 + height_bytes[1] * 2**16 + height_bytes[2] * 2**8 + height_bytes[3] print(height) # 842
内容的提问来源于stack exchange,提问作者cards
相关产品推荐
相关产品推荐

