BMP (Windows Bitmap)
| Full name | Windows Bitmap, Device-Independent Bitmap (DIB) |
|---|---|
| Extensions | .bmp, .dib |
| MIME type | image/bmp (RFC 7903); also seen: image/x-bmp, image/x-ms-bmp |
| Type | raster image, usually uncompressed (optional RLE) |
| Starts with | 42 4D (BM) |
| Specification | Bitmap Storage (Microsoft Learn) |
| Maintained by | Microsoft |
| License | documented by Microsoft, free to implement, no patents |
BMP stores a raster image as a small header followed by the pixel values, usually without compression. It supports 1, 4 and 8-bit palette images and 16, 24 and 32-bit color. Because the pixels are stored almost as they are in memory, BMP files are easy to read and write without a library, which makes the format common in Windows programs, embedded systems, bootloaders, scanners and teaching code.
The same structure without the 14-byte file header, called a DIB (device-independent bitmap), is used on the Windows clipboard (CF_DIB), inside ICO and CUR icon files and in Windows resources. A .dib file is usually a regular BMP file with a different extension, but some programs (Pillow, for one) write .dib files without the file header.
When to use BMP#
- Use when a program or device only accepts BMP (old Windows software, firmware splash screens, some printers and microcontroller displays).
- Use for quick image output from your own code: writing a 24-bit BMP takes about 30 lines with no dependencies.
- Use as a raw, lossless interchange format when speed matters more than size.
- Avoid on the web and for storage: a BMP is usually 2-10 times larger than the same image as PNG, which is also lossless.
- Avoid when you need transparency: 32-bit alpha is poorly supported across programs. Use PNG.
- Avoid for photos: use JPEG, WebP or AVIF.
File structure#
A BMP file has up to 5 parts, in this order:
| Part | Size | Description |
|---|---|---|
File header (BITMAPFILEHEADER) |
14 bytes | signature BM, file size, offset of the pixel data |
DIB header (BITMAPINFOHEADER or later) |
12-124 bytes | width, height, bits per pixel, compression, resolution, palette size |
| Bit masks | 12 or 16 bytes | only with BI_BITFIELDS and a 40-byte header |
| Color table (palette) | 4 bytes per color | B, G, R, 0 entries; required for 1, 4 and 8 bits per pixel |
| Pixel array | rest of the file | rows of pixels, each padded to a multiple of 4 bytes |
All integers are little-endian. A V5 header can also point to an embedded ICC color profile, stored after the pixel array.
File header#
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 2 | bfType |
42 4D (BM) |
| 2 | 4 | bfSize |
size of the file in bytes (don’t rely on it, some writers get it wrong) |
| 6 | 4 | bfReserved1, bfReserved2 |
0 |
| 10 | 4 | bfOffBits |
offset from the start of the file to the pixel array |
DIB header versions#
The first 4 bytes of the DIB header give its size, which identifies the version:
| Size | Name | Adds |
|---|---|---|
| 12 | BITMAPCOREHEADER (OS/2 1.x) |
16-bit width and height, palette entries of 3 bytes |
| 40 | BITMAPINFOHEADER |
the common header, read by every program |
| 64 | OS22XBITMAPHEADER (OS/2 2.x) |
OS/2 extensions (Huffman 1D, RLE24 compression) |
| 108 | BITMAPV4HEADER |
red, green, blue and alpha masks, color space, gamma |
| 124 | BITMAPV5HEADER |
rendering intent, embedded or linked ICC profile |
Fields of the 40-byte BITMAPINFOHEADER, at offset 14 in the file:
| Offset | Size | Field | Description |
|---|---|---|---|
| 14 | 4 | biSize |
header size: 40 |
| 18 | 4 | biWidth |
width in pixels (signed) |
| 22 | 4 | biHeight |
height in pixels; positive = rows stored bottom-up, negative = top-down |
| 26 | 2 | biPlanes |
always 1 |
| 28 | 2 | biBitCount |
bits per pixel: 1, 4, 8, 16, 24 or 32 |
| 30 | 4 | biCompression |
compression type, see below |
| 34 | 4 | biSizeImage |
size of the pixel data; may be 0 for BI_RGB |
| 38 | 4 | biXPelsPerMeter |
horizontal resolution (2835 = 72 DPI, 3780 = 96 DPI) |
| 42 | 4 | biYPelsPerMeter |
vertical resolution |
| 46 | 4 | biClrUsed |
number of palette entries; 0 means 2bits |
| 50 | 4 | biClrImportant |
usually 0, ignored |
Pixel data#
- Rows are stored bottom-up by default: the first row in the file is the bottom row of the image. A negative height means top-down.
- Each row is padded with zeros to a multiple of 4 bytes. Row size =
((width * bitsPerPixel + 31) / 32) * 4. - 24-bit pixels are stored as
B, G, R. 32-bit pixels areB, G, R, Xwhere the fourth byte is officially unused; many programs treat it as alpha, others ignore it. A V4 or V5 header with an alpha mask makes the alpha explicit. - 16-bit pixels are 5-5-5 (
X1R5G5B5) by default;BI_BITFIELDSmasks allow 5-6-5 and other layouts. - 1, 4 and 8-bit pixels are indexes into the color table, with the leftmost pixel in the high bits of each byte.
Compression#
| Value | Name | Description |
|---|---|---|
| 0 | BI_RGB |
uncompressed, by far the most common |
| 1 | BI_RLE8 |
run-length encoding for 8-bit images |
| 2 | BI_RLE4 |
run-length encoding for 4-bit images |
| 3 | BI_BITFIELDS |
uncompressed 16 or 32-bit with explicit color masks |
| 4 | BI_JPEG |
pixel array is a JPEG file (printers only) |
| 5 | BI_PNG |
pixel array is a PNG file (printers only) |
RLE stores pairs of (count, color index) plus escape codes for end of line, end of bitmap and position jumps. It only helps for images with long runs of one color. BI_JPEG and BI_PNG are meant for printer drivers and almost no image program reads them.
Example: a 2 x 2 24-bit BMP#
42 4D signature "BM"
46 00 00 00 file size: 70 bytes
00 00 00 00 reserved
36 00 00 00 pixel data at offset 54
28 00 00 00 DIB header size: 40 (BITMAPINFOHEADER)
02 00 00 00 width: 2
02 00 00 00 height: 2 (positive: bottom-up)
01 00 planes: 1
18 00 bits per pixel: 24
00 00 00 00 compression: BI_RGB
10 00 00 00 image size: 16 bytes
13 0B 00 00 13 0B 00 00 resolution: 2835 x 2835 pixels per meter (72 DPI)
00 00 00 00 00 00 00 00 colors used, colors important
00 00 FF FF FF FF 00 00 bottom row: red, white, 2 bytes padding
FF 00 00 00 FF 00 00 00 top row: blue, green, 2 bytes padding
Converting BMP files#
- To shrink a BMP without losing quality, convert it to PNG:
magick in.bmp out.pngwith ImageMagick or “Save as PNG” in Paint. - To create a BMP that old programs read, write 24-bit
BI_RGBwith a 40-byte header. With ImageMagick:magick in.png BMP3:out.bmp(the defaultBMPoutput uses a V4/V5 header). - To keep transparency, use PNG or ICO instead of 32-bit BMP.
Specifications and documentation#
- Bitmap Storage (Microsoft Learn): the file layout, with a hex example
- BITMAPFILEHEADER, BITMAPINFOHEADER, BITMAPV4HEADER and BITMAPV5HEADER structure reference
- Bitmap Compression (Microsoft Learn): RLE4 and RLE8 encoding
- RFC 7903: registration of the
image/bmpmedia type - BMP Suite: test images for every BMP variant, good and bad, to test decoders
- BMP file format on Wikipedia: all header versions and fields in one place
- Image file type guide (MDN): BMP support in web browsers
Software that opens BMP files#
| Software | Windows | macOS | Linux | Web | Can | Notes |
|---|---|---|---|---|---|---|
| SumatraPDF | ✓ | view | free, open source; opens .bmp and .dib | |||
| Microsoft Photos | ✓ | view, edit | built into Windows | |||
| Paint | ✓ | view, edit, create, convert | built into Windows, saves monochrome, 16, 256 color and 24-bit BMP | |||
| macOS Preview | ✓ | view, edit, convert | built into macOS | |||
| Web browsers | ✓ | ✓ | ✓ | ✓ | view | Chrome, Edge, Firefox, Safari. Also on Android and iOS |
| GIMP | ✓ | ✓ | ✓ | view, edit, create, convert | free, open source; choose RLE, 16, 24 or 32-bit on export | |
| Paint.NET | ✓ | view, edit, create, convert | free | |||
| Krita | ✓ | ✓ | ✓ | view, edit, create | free, open source | |
| IrfanView | ✓ | view, convert | free for non-commercial use, batch conversion | |||
| XnView MP | ✓ | ✓ | ✓ | view, convert | free for private use | |
| Gwenview | ✓ | view | KDE image viewer, open source | |||
| Adobe Photoshop | ✓ | ✓ | view, edit, create, convert | commercial | ||
| ImageMagick | ✓ | ✓ | ✓ | convert, create | command line, open source | |
| Photopea | ✓ | view, edit, create, convert | free, runs in the browser |
Libraries#
Open-source libraries that read and write BMP. See all BMP libraries for a comparison.
| C/C++ | SDL, stb_image |
|---|---|
| C# | ImageSharp, Magick.NET |
| Java | ImageIO, TwelveMonkeys |
| Go | imaging, x/image/bmp |
| Python | OpenCV, Pillow |
| Ruby | MiniMagick |
| Rust | image |
| PHP | GD, Imagick, Intervention Image |
Related formats#
- PNG: lossless and compressed, with full alpha; the usual replacement for BMP
- ICO: Windows icons, which store images as BMP data without the file header (or as PNG)
- TIFF: another raster format used for uncompressed and lossless images, in scanning and print
- GIF: palette images with LZW compression and animation
- TGA: simple uncompressed or RLE raster format, common in games