簡體   English   中英

從每兩個字節獲取整數值

[英]Get int value from each two bytes

我正在嘗試從圖像讀取字節,並從該圖像獲取所有int(16位)值。 解析圖片標題后,我便獲得了像素值。 當一對字節像b“ \\ xd4 \\ x00”時得到的值不正確。 在這種情況下,它應該是54272,而不是3392。

這是代碼的一部分:我使用生成器來獲取字節:

import itertools

def osddef_generator(in_file):
    with open(in_file, mode='rb') as f:
        dat = f.read()
        for byte in dat:
            yield byte

def take_slice(in_generator, size):
    return ''.join(str(chr(i)) for i in itertools.islice(in_generator, size))

def take_single_pixel(in_generator):
    pix = itertools.islice(in_generator, 2)

    hex_list = [hex(i) for i in pix]
    hex_str = "".join(hex_list)[2:].replace("0x", '')
    intval = int(hex_str, 16)
    print("hex_list: ", hex_list)
    print("hex_str: ", hex_str)
    print("intval: ", intval)

使用take_slice方法正確獲取標題后,將使用像素值進入零件,在此處使用take_single_pixel方法。 在這里,我得到了不好的結果。 這是我得到的:

hex_list:  ['0xd4', '0x0']
hex_str:  d40
intval:  3392

但是應該解釋的實際字節順序是: \\xd4\\x00 ,等於54272 ,這樣我的hex_list = ['0xd4', '0x00']hex_str = d400 當我有一個字節序列,而第二個是\\x00時,發生了某些事情。

有任何想法嗎? 謝謝!

有很多更好的方法可以將字節轉換為整數:

  • 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))

然后從那里去。 例如,請查看Pillow / PIL圖像插件源代碼 這是暴雪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))

然后是特定的屬性分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM