2009-07-22 174 views
54

我試圖在Python中讀取BMP文件。我知道前兩個字節 表示BMP公司。接下來的4個字節是文件大小。當我excecute:從Python中的二進制文件中讀取整數

fin = open("hi.bmp", "rb") 
firm = fin.read(2) 
file_size = int(fin.read(4)) 

我得到

ValueError: invalid literal for int() with base 10: 'F#\x13'

我想要做的就是閱讀這四個字節作爲一個整數什麼...看來Python是閱讀他們的字符並返回一個字符串,它不能轉換爲整數。我怎樣才能正確地做到這一點?

+2

如果你的目標是*使用*位圖,而不是花時間編寫自己的BMP庫(不是那聽起來不像有趣...),你可以使用PIL http://www.pythonware.com/產品/ pil /你可能已經安裝了。試試:import圖片 – 2009-07-22 07:24:00

+4

感謝Jared,但我想手動閱讀bmp以獲得樂趣! :) – 2009-07-22 07:33:42

回答

88

read方法以字符串形式返回一個字節序列。要從字符串字節序列轉換爲二進制數據,請使用內置的struct模塊:http://docs.python.org/library/struct.html

import struct 

print(struct.unpack('i', fin.read(4))) 

注意unpack總是返回一個元組,所以struct.unpack('i', fin.read(4))[0]給你是後的整數值。

您應該使用格式字符串'<i'(<是一個修飾符,指示little-endian字節順序和標準大小和對齊方式 - 默認情況下使用平臺的字節順序,大小和對齊方式)。根據BMP格式規範,字節應該以Intel/little-endian字節順序寫入。

+18

而不是寫`i = struct.unpack(...)[0]`我經常寫`i,= struct.unpack(...)` – 2009-07-22 10:32:30

+0

@Otto是否有任何理由您更喜歡單向的方式其他?有沒有邏輯差異? – Caltor 2012-10-16 22:45:27

+1

我覺得很奇怪,沒有內置的函數來從Python中的文件中讀取整數(或短褲等)。我不是Java專家,但我相信它具有本機功能,例如readUnsignedShort()來執行此操作。 – Caltor 2012-10-16 22:47:34

4

當你正在閱讀的二進制文件,你需要將它解壓到一個整數,所以使用結構模塊爲

import struct 
fin = open("hi.bmp", "rb") 
firm = fin.read(2) 
file_size, = struct.unpack("i",fin.read(4)) 
6

除了struct你也可以使用array模塊

import array 
values = array.array('l') # array of long integers 
values.read(fin, 1) # read 1 integer 
file_size = values[0] 
31

的不使用'struct.unpack()'的替代方法將使用NumPy

import numpy as np 

f = open("file.bin", "r") 
a = np.fromfile(f, dtype=np.uint32) 

'dtype'表示數據類型,可以是int#,uint#,float#,complex#或用戶定義的類型。請參閱numpy.fromfile

個人更喜歡使用NumPy來處理數組/矩陣數據,因爲它比使用Python列表要快得多。

2

對於Python 3.2+的,你也可以做到這一點使用from_bytes本地INT方法:

file_size = int.from_bytes(fin.read(2), byteorder='big') 

需要注意的是此功能,需要您指定的電話號碼是否是大端或小端格式進行編碼,所以你必須確定序列號以確保它能正常工作。