All formats

OpenCV

LanguagePython 3 (bindings of the C++ library)
LicenseApache 2.0
Repositorygithub.com/opencv/opencv, Python packages: opencv-python
Documentationdocs.opencv.org, imread
Depends onNumPy (the BMP codec is built into OpenCV)
Read / writeyes, 1-32 bit, RLE4, RLE8, bit fields / yes, 8-bit gray, 24-bit, 32-bit with alpha

OpenCV is a computer vision library. cv2.imread returns an image as a NumPy array and cv2.imwrite saves one; both choose the format from the file extension. The BMP codec is OpenCV’s own code, so BMP works even in minimal builds without libpng or libjpeg.

It reads palette, 16, 24 and 32-bit BMP files including RLE compression. It writes 8-bit grayscale (with a gray palette), 24-bit BGR and 32-bit BGRA files. Since OpenCV 4.13, 4-channel images are written with a V5 header and alpha mask; pass cv2.IMWRITE_BMP_COMPRESSION_RGB for the older 40-byte header. Channels are in BGR order, and imread drops alpha unless you pass cv2.IMREAD_UNCHANGED.

Installation#

Shell
pip install opencv-python
# on servers without a GUI:
pip install opencv-python-headless

Basic usage: read and write a BMP#

Python
import cv2

img = cv2.imread("in.bmp", cv2.IMREAD_UNCHANGED)
if img is None:
    raise SystemExit("cannot read in.bmp")

print(img.shape, img.dtype)  # e.g. (480, 640, 3) uint8 -> height, width, BGR

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) if img.ndim == 3 else img
if not cv2.imwrite("gray.bmp", gray):  # 8-bit BMP with a gray palette
    raise SystemExit("cannot write gray.bmp")

How to write a 32-bit BMP with alpha#

Python
import cv2

bgra = cv2.imread("in.png", cv2.IMREAD_UNCHANGED)  # 4 channels if the PNG has alpha
cv2.imwrite("alpha.bmp", bgra)  # V5 header with alpha mask (OpenCV 4.13+)

# 40-byte header, for old programs (they usually ignore the alpha byte)
cv2.imwrite("alpha-legacy.bmp", bgra,
            [cv2.IMWRITE_BMP_COMPRESSION, cv2.IMWRITE_BMP_COMPRESSION_RGB])

How to convert BMP to PNG#

Python
import cv2

img = cv2.imread("in.bmp", cv2.IMREAD_UNCHANGED)
cv2.imwrite("out.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 9])

How to encode and decode a BMP in memory#

Python
import cv2
import numpy as np

ok, buf = cv2.imencode(".bmp", img)  # 1-D uint8 array with the BMP file
bmp_bytes = buf.tobytes()

decoded = cv2.imdecode(np.frombuffer(bmp_bytes, np.uint8), cv2.IMREAD_UNCHANGED)

How to get BMP width and height#

OpenCV has no header-only reader; read the 2 fields from the BMP header with struct:

Python
import struct

with open("in.bmp", "rb") as f:
    header = f.read(26)
if header[:2] != b"BM":
    raise ValueError("not a BMP file")
width, height = struct.unpack("<ii", header[18:26])
print(width, abs(height))  # negative height means top-down rows

Tips#