提问者:小点点

BufferedReader,无法读取BMP。 TypeError:无法解包不可迭代的NoneType对象


这个程序应该从缓冲区中读取有关位图的信息。 它是用Python3.8编写的。

问题就出在这行代码上。

image_w, image_h, image_bpp, image_data = MyLoadBMP("test.bmp")

编译器会吐出错误:

TypeError: cannot unpack non-iterable NoneType object

我想错误可能是在变量的定义上,但是我不知道如何改变它。 变量是这样定义的。

这是提示,它没有改变代码。

image_w:union[无,未知]image_h:union[无,未知]image_bpp:union[无,未知]image_data:union[无,未知]

下面,我将附加与bug相关的定义函数。

def MyLoadBMP(filename):
    # Read the entire file into the buffer.
    with open(filename, "rb") as f:
        data = f.read()

    if data[:2] != 'BM':
        # Invalid BMP file.
        return None

    # Will extract BITMAPFILEHEADER
    bfType, bfSize, bfRes1, bfRes2, bfOffBits = struct.unpack("<HIHHI", data[:14])

    # Will extract BITMAPINFOHEADER.
    (biSize, biWidth, biHeight, biPlanes, biBitCount, biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUser, biClrImportant) = struct.unpack("<IIIHHIIIIII", data[14:14 + 40])

    if biSize != 40:
        # Unsupported BMP variant.
        return None
    
    if biBitCount == 24 and biCompression == 0: #BI_RGB
        return MyLoadBMP_RGB24(data, bfOffBits, biWidth, biHeight)

    # Encoding not supported.
    return None

def MyLoadBMP_RGB24(data, pixel_offset, w, h):
    # Are the poems written from bottom to top?
    bottom_up = True
    if h < 0:
        bottom_up = False
        h = - h
    
    # Calculate the pitch.
    pitch = (w * 3 + 3) & ~3

    # Create a new buffer for the read bitmap (24BPP, color order: BGR).

    bitmap = array.array('B', [0]) * w * h * 3

    # Load lines.
    if bottom_up:
        r = range(h - 1, -1, -1)
    else:
        r = range(0, h)

    for y in r:
        for x in range(0, w):
            bitmap[(x + y * w * 3 + 0)] = ord(data[pixel_offset + x * 3 + 0])
            bitmap[(x + y * w * 3 + 1)] = ord(data[pixel_offset + x * 3 + 1])
            bitmap[(x + y * w * 3 + 2)] = ord(data[pixel_offset + x * 3 + 2])
        pixel_offset += pitch

    return (w, h, 24, bitmap)

共1个答案

匿名用户

您的函数返回none,可能是因为您在代码中遇到了以下三种情况之一:

if data[:2] != 'BM':
    # Invalid BMP file.
    return None

# ...

if biSize != 40:
    # Unsupported BMP variant.
    return None

if biBitCount == 24 and biCompression == 0: #BI_RGB
    # ...

# Encoding not supported.
return None

无法解压缩:

>>> image_w, image_h, image_bpp, image_data = None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

先测试结果,然后解包:

result = MyLoadBMP("test.bmp")
if result is None:
    # handle separately
else:
    image_w, image_h, image_bpp, image_data = result