pythonimagebitmapbitbit-depth

How to get bit depth of a bitmap image


I have images where I want to know the bit depth of the .bmp image. This is quite easy in windows manually (Properties>Details..) but there doesn't seem to much from google on it and the one answer I saw on here didn't (for me) show how to do it.

How to find the Bit Depth of an image

Code

import png as png
import numpy as np

r=png.Reader(filename = r'C:\Users\priper\Desktop\OPW_refac\grayscale.png')
a = r.read()

print(a[3]['bitdepth'])

or

from PIL import Image
import numpy as np

#Load the BMP file    
img = Image.open(r'C:\Users\priper\Desktop\OPW_refac\HSS All As.bmp')
print(img, '\n')
print('bit depth :', img.mode)#this only tells me it is 8 pixels, I don't think it could tell me if it was 4.

#Or as a numpy array
img = np.array(Image.open(r'C:\Users\priper\Desktop\OPW_refac\HSS All As.bmp'))
print(img)

I can read the bit depth of a png but haven't a clue which library can get similar information so easily from a bmp.


Solution

  • You would probably be better off with a proper library, like wand or exiftool, but if you want something lightweight, this might be good enough - but I can't test it on your images as you haven't shared any:

    #!/usr/bin/env python3
    
    import sys
    import struct
    
    # Read first 100 bytes
    with open('a.bmp','rb') as f:
        BMP = f.read(100)
    
    if BMP[0:2] != b'BM':
       sys.exit('ERROR: Incorrect BMP signature')
    
    # Get BITMAPINFOHEADER size - https://en.wikipedia.org/wiki/BMP_file_format
    BITMAPINFOHEADERSIZE = struct.unpack('<i',BMP[14:18])[0]
    okSizes = [40, 52, 56, 108, 124]
    if BITMAPINFOHEADERSIZE not in okSizes:
       sys.exit(f'ERROR: BITMAPINFOHEADER size was {BITMAPINFOHEADERSIZE}, expected one of {okSizes}')
    
    # Get bits per pixel
    bpp = struct.unpack('<H',BMP[28:30])[0]
    print(f'bbp: {bpp}')
    

    I created a sample BMP with ImageMagick like this:

    magick -size 32x32 xc:red -define bmp:subtype=RGB565  a.bmp
    

    I then ran my script and got bpp:16 matching exiftool output:

    exiftool a.bmp
    
    ExifTool Version Number         : 12.00
    File Name                       : a.bmp
    Directory                       : .
    File Size                       : 2.1 kB
    File Modification Date/Time     : 2021:02:24 12:01:51+00:00
    File Access Date/Time           : 2021:02:24 12:01:52+00:00
    File Inode Change Date/Time     : 2021:02:24 12:01:51+00:00
    File Permissions                : rw-r--r--
    File Type                       : BMP
    File Type Extension             : bmp
    MIME Type                       : image/bmp
    BMP Version                     : Windows V5
    Image Width                     : 32
    Image Height                    : 32
    Planes                          : 1
    Bit Depth                       : 16           <--- HERE IT IS
    Compression                     : Bitfields
    Image Length                    : 2048
    Pixels Per Meter X              : 0
    Pixels Per Meter Y              : 0
    Num Colors                      : Use BitDepth
    Num Important Colors            : All
    Red Mask                        : 0x0000f800
    Green Mask                      : 0x000007e0
    Blue Mask                       : 0x0000001f
    Alpha Mask                      : 0x00000000
    Color Space                     : sRGB
    Rendering Intent                : Picture (LCS_GM_IMAGES)
    Image Size                      : 32x32
    Megapixels                      : 0.001
    

    I then created a 24-bit BMP like this:

    magick -size 32x32 xc:red a.bmp
    

    and both my Python and exiftool report 24 bpp.

    Keywords: Python. BMP, image processing, get depth, bit-depth, bpp.