Существуют гораздо лучшие способы преобразования байтов в целые числа:
int.from_bytes()
принимает входные байты и аргумент порядка следования байтов:
>>> int.from_bytes(b"\xd4\x00", 'big')
54272
>>> int.from_bytes(b"\xd4\x00", 'little')
212
Функция struct.unpack()
позволяет преобразовать целую серию байтов в целые числа, следуя шаблону:
>>> import struct
>>> struct.unpack('!4H', b'\xd4\x00\xd4\x00\xd4\x00\xd4\x00')
(54272, 54272, 54272, 54272)
Модуль array
позволяет эффективно считывать двоичные данные, представляющие однородные целочисленные данные, в структуру памяти:
>>> array.array('H', fileobject)
Однако array
нельзя сказать, какой порядок байтов использовать,Вам нужно будет определить текущий порядок байтов архитектуры и вызвать arr.byteswap()
, чтобы изменить порядок, если машинный порядок не соответствует порядку файлов.
При чтении данных изображения этопочти всегда предпочтительнее использовать модуль struct
для анализа.Обычно вы используете file.read()
звонки с определенными размерами;если заголовок состоит из 10 байтов, используйте:
headerinfo = struct.unpack('<expected header pattern for 10 bytes>', f.read(10))
и перейдите оттуда.Для примера, посмотрите исходный код Подушек / PIL-плагинов ;вот как читается заголовок формата изображения Blizzard Mipmap :
def _read_blp_header(self):
self._blp_compression, = struct.unpack("<i", self.fp.read(4))
self._blp_encoding, = struct.unpack("<b", self.fp.read(1))
self._blp_alpha_depth, = struct.unpack("<b", self.fp.read(1))
self._blp_alpha_encoding, = struct.unpack("<b", self.fp.read(1))
self._blp_mips, = struct.unpack("<b", self.fp.read(1))
self._size = struct.unpack("<II", self.fp.read(8))
if self.magic == b"BLP1":
# Only present for BLP1
self._blp_encoding, = struct.unpack("<i", self.fp.read(4))
self._blp_subtype, = struct.unpack("<i", self.fp.read(4))
self._blp_offsets = struct.unpack("<16I", self.fp.read(16 * 4))
self._blp_lengths = struct.unpack("<16I", self.fp.read(16 * 4))
Поскольку struct.unpack()
всегда возвращает кортежи, вы можете назначить отдельные элементы в кортеже именам name1, name2, ...
наразмер левой руки, включая single_name, =
присваивания для извлечения одного результата.
Отдельный набор вызовов для чтения выше также может быть сжат в меньшее количество вызовов:
comp, enc, adepth, aenc, mips, *size = struct.unpack("<i4b2I", self.fp.read(16))
if self.magic == b"BLP1":
# Only present for BLP1
enc, subtype = struct.unpack("<2i", self.fp.read(8))
, за которым следует определенный атрибутзадания.