All formats

Pillow

LanguagePython 3
LicenseMIT-CMU (permissive)
Repositorygithub.com/python-pillow/Pillow
Documentationpillow.readthedocs.io, BMP format notes
Depends onnothing extra for BMP (binary wheels include all codecs)
Read / writeyes, 1, 4, 8, 16, 24 and 32-bit, RLE4, RLE8, bit fields, OS/2 / yes, 1-bit, 8-bit gray or palette, 24-bit, 32-bit; no RLE output

Pillow is the default image library for Python. Its BMP plugin reads Windows and OS/2 bitmaps with any common bit depth, RLE compression and bit field masks, and DIB data without the file header. It writes uncompressed BMP with a 40-byte header.

The BMP bit depth follows the image mode: 1 gives 1-bit, L and P give 8-bit palette files, RGB gives 24-bit and RGBA gives 32-bit. The 32-bit output uses a plain BITMAPINFOHEADER, so many programs ignore its alpha channel.

Installation#

Shell
pip install pillow

Basic usage: open, edit and save a BMP#

Python
from PIL import Image, ImageOps

with Image.open("in.bmp") as im:
    print(im.size, im.mode, im.info.get("compression"))  # compression: 0 = none, 1 = RLE8, 2 = RLE4
    im = ImageOps.mirror(im)
    im.save("out.bmp")

How to get BMP width and height without decoding#

Image.open reads only the header; pixels are decoded on first access:

Python
from PIL import Image

with Image.open("in.bmp") as im:
    width, height = im.size
    print(width, height, im.mode, im.info.get("dpi"))

How to save a BMP with a specific bit depth#

Convert the image to the mode that matches the bit depth you need:

Python
from PIL import Image

with Image.open("in.png") as im:
    im.convert("RGB").save("24bit.bmp")                  # 24-bit
    im.convert("L").save("gray8.bmp")                    # 8-bit grayscale palette
    im.convert("RGB").quantize(colors=256).save("palette8.bmp")  # 8-bit color palette
    im.convert("1").save("mono.bmp")                     # 1-bit black and white, dithered

How to convert PNG to BMP#

Flatten transparency onto a background color so programs that ignore BMP alpha show the image correctly:

Python
from PIL import Image

with Image.open("in.png") as im:
    im = im.convert("RGBA")
    bg = Image.new("RGB", im.size, (255, 255, 255))
    bg.paste(im, mask=im.getchannel("A"))
    bg.save("out.bmp")

How to convert BMP to PNG#

Python
from PIL import Image

with Image.open("in.bmp") as im:
    im.save("out.png", optimize=True)

A 24-bit BMP is often 2-10 times larger than the same image as PNG.

How to set the resolution (DPI)#

Python
im.save("out.bmp", dpi=(300, 300))  # stored as pixels per meter in the header

Tips#