Python学习笔记__12.4章 struct

1、概览

struct模块用于解决bytes和其他二进制数据类型的转换

 

        1)structpack函数把任意数据类型变成bytes

>>> import struct

>>> struct.pack('>I', 10240099)

b'\x00\x9c@c'

pack的参数:

第一个参数是处理指令:

'>I'的意思是:>表示字节顺序是big-endian,也就是网络字节序,I表示4字节无符号整数。

第二个参数是传入的参数:

传入的参数个数要和处理指令一致。

 

        2)unpackbytes变成相应的数据类型:

>>> struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')

(4042322160, 32896)

根据>IH的说明,后面的bytes依次变为:

I:4字节无符号整数和 H:2字节无符号整数。

        3)bmp文件的unpack

# 用画图,画一个bmp文件,读入前30个字节进行分析

>>> s = b'\x42\x4d\x38\x8c\x0a\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\x68\x01\x00\x00\x01\x00\x18\x00'

# 用unpack读取

>>> struct.unpack('<ccIIIIIIHH', s)  # < 表示字节序是主机字节序 Little endian

(b'B', b'M', 691256, 0, 54, 40, 640, 360, 1, 24)

两个字节:'BM'表示Windows位图,'BA'表示OS/2位图;

一个4字节整数:表示位图大小;

一个4字节整数:保留位,始终为0;

一个4字节整数:实际图像的偏移量;

一个4字节整数:Header的字节数;

一个4字节整数:图像宽度;

一个4字节整数:图像高度;

一个2字节整数:始终为1;

一个2字节整数:颜色数。

结果显示,b'B'b'M'说明是Windows位图,位图大小为640x360,颜色数为24。

        4)参考文档

struct模块定义的数据类型 (https://docs.python.org/3/library/struct.html#format-characters)

Python网络字节序和主机字节序 (https://www.linuxidc.com/Linux/2014-02/97157.htm)

2、例子

1、编写一个bmpinfo.py,可以检查任意文件是否是位图文件,如果是,打印出图片大小和颜色数

# -*- coding: utf-8 -*-

import base64, struct

bmp_data = base64.b64decode('Qk1oAgAAAAAAADYAAAAoAAAAHAAAAAoAAAABABAAAAAAADICAAASCwAAEgsAAAAAAAAAAAAA/3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9/AHwAfAB8AHwAfAB8AHwAfP9//3//fwB8AHwAfAB8/3//f/9/AHwAfAB8AHz/f/9//3//f/9//38AfAB8AHwAfAB8AHwAfAB8AHz/f/9//38AfAB8/3//f/9//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9//3//fwB8AHz/f/9//3//f/9/AHwAfP9//3//f/9//3//f/9//38AfAB8AHwAfAB8AHwAfP9//3//f/9/AHwAfP9//3//f/9//38AfAB8/3//f/9//3//f/9//3//fwB8AHwAfAB8AHwAfAB8/3//f/9//38AfAB8/3//f/9//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9//3//fwB8AHz/f/9/AHz/f/9/AHwAfP9//38AfP9//3//f/9/AHwAfAB8AHwAfAB8AHwAfAB8/3//f/9/AHwAfP9//38AfAB8AHwAfAB8AHwAfAB8/3//f/9//38AfAB8AHwAfAB8AHwAfAB8/3//f/9/AHwAfAB8AHz/fwB8AHwAfAB8AHwAfAB8AHz/f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//38AAA==')

 

def bmp_info(data):

    str=struct.unpack('<ccIIIIIIHH',data[:30]) #bytes类也有切片方法

    if str[0]==b'B' and str[1]==b'M':

        print("这是位图文件")

        return {

            'width': str[-4],

            'height': str[-3],

            'color': str[-1]

                }

    else:

        print("这不是位图文件")

# 测试

bi = bmp_info(bmp_data)

assert bi['width'] == 28

assert bi['height'] == 10

assert bi['color'] == 16

print('ok')


猜你喜欢

转载自blog.51cto.com/12758568/2117088