Pythonで [〜#〜] bmp [〜#〜] ファイルを読み取ろうとしています。最初の2バイトはBMP firm。を示しています。次の4バイトはファイルサイズです。実行すると:
fin = open("hi.bmp", "rb")
firm = fin.read(2)
file_size = int(fin.read(4))
私は得る:
ValueError:基数10のint()の無効なリテラル: 'F#\ x13'
私がやりたいのは、これらの4バイトを整数として読み取ることですが、Pythonはそれらを文字として読み取り、整数に変換できない文字列を返しているようです。正しく?
read
メソッドは、バイトシーケンスを文字列として返します。文字列のバイトシーケンスからバイナリデータに変換するには、組み込みのstruct
モジュールを使用します: http://docs.python.org/library/struct.html 。
_import struct
print(struct.unpack('i', fin.read(4)))
_
unpack
は常にTupleを返すので、struct.unpack('i', fin.read(4))[0]
はあなたが後の整数値を与えることに注意してください。
おそらくフォーマット文字列_'<i'
_を使用する必要があります(<は、リトルエンディアンのバイト順と標準のサイズとアライメントを示す修飾子です-デフォルトでは、プラットフォームのバイト順、サイズ、アライメントを使用します)。 BMP形式仕様に従って、バイトはIntel /リトルエンディアンのバイト順で書き込まれる必要があります。
'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リストを使用するよりもはるかに高速です。
Python 3.2+以降、 from_bytes
ネイティブintメソッド:
file_size = int.from_bytes(fin.read(2), byteorder='big')
この関数では、数値をビッグエンディアン形式とリトルエンディアン形式のどちらでエンコードするかを指定する必要があるため、エンディアンを判断して正しく機能することを確認する必要があります。
struct
を除き、array
モジュールも使用できます。
import array
values = array.array('l') # array of long integers
values.read(fin, 1) # read 1 integer
file_size = values[0]
バイナリファイルを読んでいるときに、整数に展開する必要があるため、そのためにstructモジュールを使用します
import struct
fin = open("hi.bmp", "rb")
firm = fin.read(2)
file_size, = struct.unpack("i",fin.read(4))
バイナリファイルから読み取るときは、バイトと呼ばれるデータ型が使用されます。これはリストまたはタプルに少し似ていますが、0から255までの整数しか保存できないことを除きます。
試してください:
file_size = fin.read(4)
file_size0 = file_size[0]
file_size1 = file_size[1]
file_size2 = file_size[2]
file_size3 = file_size[3]
または:
file_size = list(fin.read(4))
の代わりに:
file_size = int(fin.read(4))