如何在python中读取bmp文件头?

时间:2017-10-29 18:37:45

标签: python image-processing bitmap bmp

我需要用python读取bmp文件的标题。我试过这样,但它显然只返回一堆不可理解的字节:

f = open(input_filename,"rb")
data = bytearray(f.read())
f.close()
print(data[:14])

我的想法是找到一个模块或快速的东西,以便在打开时记录图像信息。我在matlab中知道这个函数,它完全符合我的要求:imfinfo()。但我无法在python中找到对应物。

要清楚,这是我用matlab得到的:

       FileModDate: '20-Oct-2017 09:42:24'
          FileSize: 1311798
            Format: 'bmp'
     FormatVersion: 'Version 3 (Microsoft Windows 3.x)'
             Width: 1280
            Height: 1024
          BitDepth: 8
         ColorType: 'indexed'
   FormatSignature: 'BM'
NumColormapEntries: 256
          Colormap: [256x3 double]
           RedMask: []
         GreenMask: []
          BlueMask: []
   ImageDataOffset: 1078
  BitmapHeaderSize: 40
         NumPlanes: 1
   CompressionType: 'none'
        BitmapSize: 1310720
    HorzResolution: 0
    VertResolution: 0
     NumColorsUsed: 256
NumImportantColors: 0

2 个答案:

答案 0 :(得分:2)

您可以使用imghdr module(位于python stdlib中):

>>> import imghdr
>>> print(imghdr.what(input_filename))
bmp

这将从标题中提取图像类型,但这就是全部。 Python标准库中没有任何其他内容可以获取更详细的信息 - 您需要第三方库来执行此类专门任务。要了解其复杂性,请查看BMP file format。基于那里概述的规范,编写一些纯Python代码来提取一些信息项可能是可行的,但是对于任意位图图像文件来说它是不容易的。

<强>更新

下面是一个简单的脚本,用于使用struct module从位图头中提取一些基本信息。请参阅上面提到的BMP文件格式,了解如何解释各种值,并注意此脚本仅适用于最常见的格式版本(即Windows BITMAPINFOHEADER):

import struct

bmp = open(fn, 'rb')
print('Type:', bmp.read(2).decode())
print('Size: %s' % struct.unpack('I', bmp.read(4)))
print('Reserved 1: %s' % struct.unpack('H', bmp.read(2)))
print('Reserved 2: %s' % struct.unpack('H', bmp.read(2)))
print('Offset: %s' % struct.unpack('I', bmp.read(4)))

print('DIB Header Size: %s' % struct.unpack('I', bmp.read(4)))
print('Width: %s' % struct.unpack('I', bmp.read(4)))
print('Height: %s' % struct.unpack('I', bmp.read(4)))
print('Colour Planes: %s' % struct.unpack('H', bmp.read(2)))
print('Bits per Pixel: %s' % struct.unpack('H', bmp.read(2)))
print('Compression Method: %s' % struct.unpack('I', bmp.read(4)))
print('Raw Image Size: %s' % struct.unpack('I', bmp.read(4)))
print('Horizontal Resolution: %s' % struct.unpack('I', bmp.read(4)))
print('Vertical Resolution: %s' % struct.unpack('I', bmp.read(4)))
print('Number of Colours: %s' % struct.unpack('I', bmp.read(4)))
print('Important Colours: %s' % struct.unpack('I', bmp.read(4)))

输出:

Type: BM
Size: 287518
Reserved 1: 0
Reserved 2: 0
Offset: 1078
DIB Header Size: 40
Width: 657
Height: 434
Colour Planes: 1
Bits per Pixel: 8
Compression Method: 0
Raw Image Size: 286440
Horizontal Resolution: 11811
Vertical Resolution: 11811
Number of Colours: 256
Important Colours: 0        

答案 1 :(得分:1)

这里是一个简短的例子,如何使用 struct module 提取整个 bmp 头信息。

import struct

with open(file_name, "rb") as f:
     file_data = f.read()

header_data = struct.unpack('<2sIHHIIIIHHIIIIII', file_data[:54])

print(header_data)

输出:

(b'BM', 690, 0, 0, 150, 124, 15, 9, 1, 32, 3, 0, 3780, 3780, 0, 0)

如果您不想保存整个标题数据,而只想从中获取一个值,您可以使用 unpack_from() 函数,该函数可用于获取特定偏移量的数据.

这是一个例子:

import struct

with open(file_name, "rb") as f:
     file_data = f.read()

image_width = struct.unpack_from('<i', file_data, 18)[0]
image_height = struct.unpack_from('<i', file_data, 22)[0]

print(image_width, image_height)