在Python中阅读bmp文件

insrf1ej  于 2023-10-21  发布在  Python
关注(0)|答案(9)|浏览(190)

有没有一种方法可以在Python中读取bmp文件,而不需要使用PIL?PIL不适用于版本3,这是我拥有的版本。我尝试使用来自www.example.com的Image对象Imagegraphics.py(anchorPoint,filename),但似乎只能处理gif文件。

wi3ka0sx

wi3ka0sx1#

在Python中,它可以简单地读作:

import os
from scipy import misc
path = 'your_file_path'
image= misc.imread(os.path.join(path,'image.bmp'), flatten= 0)

## flatten=0 if image is required as it is 
## flatten=1 to flatten the color layers into a single gray-scale layer
8yparm6h

8yparm6h2#

我知道这是一个老问题,但我发现它时,解决这个问题,我自己和我认为,这可能会帮助别人在未来。
实际上,将BMP文件作为二进制数据读取非常容易。当然,这取决于您需要支持的支持范围有多广以及有多少个角落案例。
下面是一个简单的解析器,只适用于1920x1080 24位BMP(如从MS Paint保存的)。但它应该很容易扩展。它将像素值吐出为python列表,例如红色图像的(255, 0, 0, 255, 0, 0, ...)
如果你需要更强大的支持,这里有关于如何正确阅读这个问题的答案的信息:How to read bmp file header in python?。使用这些信息,您应该能够扩展下面的简单解析器,使其具有您需要的任何特性。
如果你需要的话,在wikipedia https://en.wikipedia.org/wiki/BMP_file_format上还有更多关于BMP文件格式的信息。

def read_rows(path):
    image_file = open(path, "rb")
    # Blindly skip the BMP header.
    image_file.seek(54)

    # We need to read pixels in as rows to later swap the order
    # since BMP stores pixels starting at the bottom left.
    rows = []
    row = []
    pixel_index = 0

    while True:
        if pixel_index == 1920:
            pixel_index = 0
            rows.insert(0, row)
            if len(row) != 1920 * 3:
                raise Exception("Row length is not 1920*3 but " + str(len(row)) + " / 3.0 = " + str(len(row) / 3.0))
            row = []
        pixel_index += 1

        r_string = image_file.read(1)
        g_string = image_file.read(1)
        b_string = image_file.read(1)

        if len(r_string) == 0:
            # This is expected to happen when we've read everything.
            if len(rows) != 1080:
                print "Warning!!! Read to the end of the file at the correct sub-pixel (red) but we've not read 1080 rows!"
            break

        if len(g_string) == 0:
            print "Warning!!! Got 0 length string for green. Breaking."
            break

        if len(b_string) == 0:
            print "Warning!!! Got 0 length string for blue. Breaking."
            break

        r = ord(r_string)
        g = ord(g_string)
        b = ord(b_string)

        row.append(b)
        row.append(g)
        row.append(r)

    image_file.close()

    return rows

def repack_sub_pixels(rows):
    print "Repacking pixels..."
    sub_pixels = []
    for row in rows:
        for sub_pixel in row:
            sub_pixels.append(sub_pixel)

    diff = len(sub_pixels) - 1920 * 1080 * 3
    print "Packed", len(sub_pixels), "sub-pixels."
    if diff != 0:
        print "Error! Number of sub-pixels packed does not match 1920*1080: (" + str(len(sub_pixels)) + " - 1920 * 1080 * 3 = " + str(diff) +")."

    return sub_pixels

rows = read_rows("my image.bmp")

# This list is raw sub-pixel values. A red image is for example (255, 0, 0, 255, 0, 0, ...).
sub_pixels = repack_sub_pixels(rows)
eeq64g8w

eeq64g8w3#

用枕头做这个。安装后,只需导入

from PIL import Image

然后你可以加载BMP文件

img = Image.open('path_to_file\file.bmp')

如果需要图像是numpy数组,请使用np.array

img = np.array(Image.open('path_to_file\file.bmp'))

numpy数组将仅为1D。使用reshape()将其变成正确的形状,以防您的图像是RGB。举例来说:

np.array(Image.open('path_to_file\file.bmp')).reshape(512,512,3)
fjaof16o

fjaof16o4#

使用优秀的matplotlib库

import matplotlib.pyplot as plt
im = plt.imread('image.bmp')
kupeojn6

kupeojn65#

我不得不在一个项目上工作,我需要使用Python读取BMP文件,这很有趣,实际上最好的方法是对BMP文件格式(https://en.wikipedia.org/wiki/BMP_file_format)进行审查,然后阅读它作为二进制文件,以提取数据。
您将需要使用structpython库来执行提取
您可以使用本教程来了解它如何进行https://youtu.be/0Kwqdkhgbfw

u59ebvdq

u59ebvdq6#

这取决于你想实现什么,在哪个平台上?
无论如何,使用C库加载BMP可能会工作,例如。http://code.google.com/p/libbmp/http://freeimage.sourceforge.net/,C库可以很容易地从python调用,例如。使用ctypes或将其 Package 为python模块。
或者您可以编译此版本的PIL https://github.com/sloonz/pil-py3k

798qvoo8

798qvoo87#

如果你在Windows中这样做,这个网站应该允许你在大多数版本的Python中启动和运行PIL(和许多其他流行的包):Unofficial Windows Binaries for Python Extension Packages

42fyovps

42fyovps8#

PIL到Python 3.x的公共端口称为“Pillow”。我也建议Pygame库用于简单的任务。它是一个库,充满了创建游戏的功能-和阅读从一些常见的图像格式是其中之一。Python 3.x也是如此。

xam8gpfp

xam8gpfp9#

前一段时间,我需要从一个旧的科学软件中读取BMP,它在一些程序中工作,但Python的PIL拒绝打开它。
BMP是一种相当简单的格式,很容易被numpy解析;您可能希望修改以下几行。

def load_Philips30XL_BMP(fname):
    """ 
    Experimental loading of BMPs from Philips30XL microscopes (they have an atypical format which cannot be loaded by imageio)
    See https://ide.kaitai.io/ for more information on BMP header. 
    """
    with open(fname, mode='rb') as file: # first analyze the header
        fileContent = file.read()
        ofs, w, h, bpp, compr = [int.from_bytes(fileContent[s:e], byteorder='little', signed=False) for s,e in 
                ((0x0a,0x0e),(0x12,0x16),(0x16,0x1a),(0x1c,0x1e),(0x1e,0x22))]
    assert bpp == 8, f'monochrome/LUT image assumed (8 bit per pixel); {fname} has {bpp}bpp'
    assert compr == 0, 'no decompression algorithm implemented'
    return np.fromfile(fname, dtype=np.uint8)[ofs:ofs+w*h].reshape(h,w)[::-1,:] # BMP is "upside down" - flip vertically

相关问题