Я пытаюсь прочитать файл BMP на Python. Я знаю, что первые два байта указывают фирму BMP. Следующие 4 байта - это размер файла. Когда я выполняю:
fin = open("hi.bmp", "rb")
firm = fin.read(2)
file_size = int(fin.read(4))
Я получил:
ValueError: недопустимый литерал для int () с базой 10: 'F # \ x13'
Я хочу читать эти четыре байта как целое число, но кажется, что Python читает их как символы и возвращает строку, которую нельзя преобразовать в целое число. Как мне это сделать правильно?
Ответы:
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'
(<- это модификатор, который указывает порядок байтов с прямым порядком байтов, стандартный размер и выравнивание - по умолчанию используется порядок байтов, размер и выравнивание платформы). Согласно спецификации формата BMP, байты должны быть записаны в порядке байтов Intel / little-endian.источник
i = struct.unpack(...)[0]
я часто пишуi, = struct.unpack(...)
Альтернативный метод, который не использует struct.unpack (), - использовать NumPy :
import numpy as np f = open("file.bin", "r") a = np.fromfile(f, dtype=np.uint32)
'dtype' представляет тип данных и может быть int #, uint #, float #, сложным # или определяемым пользователем типом. Смотрите
numpy.fromfile
.Лично я предпочитаю использовать NumPy для работы с данными массива / матрицы, так как это намного быстрее, чем использование списков Python.
источник
a = np.fromfile('file.bin', dtype=np.uint32)
Начиная с 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]
источник
array
- это эффективный способ чтения двоичного файла, но не очень гибкий, когда нам приходится иметь дело со структурой, как вы правильно заметили.Когда вы читаете двоичный файл, вам нужно распаковать его в целое число, поэтому используйте для этого struct module
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))
источник