|
如你所见, Python 中有许多文本处理工具(模块、函数等),然而处理二进制数据的工具则要少得多。 标准库里有一个 struct 模块,专门用于处理类似 C 和 C++ 中结构体的数据。你可以使用 struct 模块的功能将二进制数据转换为 Python 中的数据结构。
以一个 PNG 文件(一种常见的图片格式,其他图片格式还有 GIF、 JPEG 等)为例看看struct 是如何工作的。我们来编写一个小程序,从 PNG 文件中获得图片的宽度和高度信息。
使用 O’Reilly 的经典标志:一只睁大了眼睛的眼镜猴,见下图。
你可以在 Wikipedia(http://upload.wikimedia.org/wikipedia/en/9/95/O’Reilly_logo.png)上获取这张图片的 PNG 文件。第 8 章之前都不会讨论读取文件的方法,因此这里我仅仅是将这个文件下载下来, 并编写了一个简单的小程序将它的数据以字节形式打印出来,然后将起始的 30 字节数据存入 Pythonbytes 型变量 data 中,如下所示。方便起见,你只需复制这部分数据即可。(PNG 格式规定了图片的宽度和高度信息存储在初始 24 字节中,因此不需要其他的额外数据。)
代码:- import struct
- valid_png_header = b'\x89PNG\r\n\x1a\n'
- data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR' + \
- b'\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0'
- if data[:8] == valid_png_header:
- width, height = struct.unpack('>LL', data[16:24])
- print('Valid PNG, width', width, 'height', height)
- else:
- print('Not a valid PNG')
复制代码 输出结果:
Valid PNG, width 154 height 141
以上代码说明:
• data 包含了 PNG 文件的前 30 字节内容,为了书的排版,我将这 30 字节数据放到了两行字节串中,并用 + 和续行符(\)将它们连接起来;
• valid_png_header 包含 8 字节序列,它标志着这是一个有效的 PNG 格式文件;
• width 值位于第 16~20 字节, height 值则位于第 21~24 字节。
上面代码中的 >LL 是一个格式串,它用于指导 unpack() 正确解读字节序列并将它们组装成Python 中的数据类型。可以将它分解成下面几个基本格式标志:
• > 用于指明整数是以大端(big-endian)方案存储的;
• 每个 L 代表一个 4 字节的无符号长(unsigned long)整数。
你可以直接获取 4 字节数据:
>>> data[16:20]
b'\x00\x00\x00\x9a'
>>> data[20:24]0x9a
b'\x00\x00\x00\x8d'
大端方案将高字节放在左侧。由于宽度和高度都小于 255,因此它们存储在每一个 4 字节序列的最后一字节中。 不难验证,上面的十六进制数转换为十进制后与我们预期的数值(图片的宽和高)一致:>>> 0x9a
154
>>> 0x8d
141
如果想要执行上述过程的逆过程,将 Python 数据转换为字节,可以使用 struct pack()函数:
>>> import struct
>>> struct.pack('>L', 154)
b'\x00\x00\x00\x9a'
>>> struct.pack('>L', 141)
b'\x00\x00\x00\x8d'
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|