一.struct內建模塊
Python提供了一個struct模塊來解決bytes和其他二進制數據類型的轉換。
struct的pack函數把任意數據類型變成bytes:
>>> import struct
>>> struct.pack('>I', 10240099)
b'\x00\x9c@c'
pack的第一個參數是處理指令,’>I’的意思是:
>表示字節順序是big-endian,也就是網絡序,I表示4字節無符號整數。
後面的參數個數要和處理指令一致。
unpack把bytes變成相應的數據類型:
>>> struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')
(4042322160, 32896)
根據>IH的說明,後面的bytes依次變爲I:4字節無符號整數和H:2字節無符號整數。
struct模塊定義的數據類型可以參考Python官方文檔:
https://docs.python.org/3/library/struct.html#format-characters
二.bmp圖片
Windows的位圖文件(.bmp)是一種非常簡單的文件格式,我們來用struct分析一下。
首先找一個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'
BMP格式採用小端方式存儲數據,文件頭的結構按順序如下:
兩個字節:’BM’表示Windows位圖,’BA’表示OS/2位圖;
一個4字節整數:表示位圖大小;
一個4字節整數:保留位,始終爲0;
一個4字節整數:實際圖像的偏移量;
一個4字節整數:Header的字節數;
一個4字節整數:圖像寬度;
一個4字節整數:圖像高度;
一個2字節整數:始終爲1;
一個2字節整數:顏色數。
所以,組合起來用unpack讀取:
>>> struct.unpack('<ccIIIIIIHH', s)
(b'B', b'M', 691256, 0, 54, 40, 640, 360, 1, 24)
結果顯示,b’B’、b’M’說明是Windows位圖,位圖大小爲640x360,顏色數爲24。
讀取文件判斷
import base64, struct
with open('test.bmp', 'rb') as f:
s = f.read(30)
print(s)
def bmp_info():
unpackbuf = struct.unpack('<ccIIIIIIHH', s)
if (unpackbuf[0] != b'B' or unpackbuf[1] != b'M'):
return None
else:
return {
'width' : unpackbuf[6],
'height': unpackbuf[7],
'color' : unpackbuf[9]
}
bi = bmp_info()
print(bi['width'], bi['height'], bi['color'])