Tiefenblick

BMP-Format erklärt: Windows' einfachstes Bildformat

koboshiCo-founder
·11 min Lesezeit
BMP-Format erklärt: Windows' einfachstes Bildformat
Zusammenfassung

BMP gehört seit Windows 3.0 von 1990 zum Standard. Es speichert rohe Pixel mit minimalen Headern, ohne Kompression und ohne Alpha. Der Artikel erklärt den Aufbau vom 14-Byte-BITMAPFILEHEADER bis zu den Einsatzgebieten in eingebetteten Systemen und der medizinischen Bildgebung.

Wer eine BMP-Datei in einem Hex-Editor öffnet, sieht in den ersten vierzehn Bytes Folgendes:

42 4D 46 00 00 00 00 00 00 00 36 00 00 00

Das ist der gesamte BITMAPFILEHEADER. 42 4D ist die Signatur "BM" in ASCII. Die nächsten vier Bytes geben die Dateigröße an — 46 00 00 00 ist Little-Endian für 70. Die folgenden vier Bytes sind reserviert und immer Null. Die letzten vier Bytes enthalten den Offset zu den Pixeldaten — 36 00 00 00 entspricht 54, also beginnt das Pixel-Array bei Byte 54.

Kein Kompressionsmarker. Kein Farbprofil. Kein Alphakanal. Nur eine Signatur, eine Größe und ein Offset. BMP ist, wie der Name nahelegt, eine direkte Bit-Abbildung.

Was BMP eigentlich ist

BMP steht für Bitmap, oder formeller Device Independent Bitmap (DIB). Microsoft führte es mit Windows 3.0 im Jahr 1990 ein, um Rasterbilder zu speichern, ohne sie an ein bestimmtes Anzeigegerät zu binden. Vor DIB verwendete Windows Device Dependent Bitmaps (DDB), deren Pixelformat zur jeweils installierten Grafikkarte passte. Eine auf einem Rechner gespeicherte DDB konnte auf einem anderen nicht lesbar sein.

BMP löste das, indem es genug Metadaten in der Datei speicherte, damit jeder Decoder das Bild rekonstruieren konnte: Breite, Höhe, Farbtiefe, Farbpalette, Kompressionstyp und das rohe Pixel-Array. Das Betriebssystem liest den Header, reserviert einen Puffer und kopiert die Pixel in den Speicher. Bei 24-Bit-unkomprimierten Bildern sind die Pixeldaten meist einfache RGB-Tripel, bottom-up zeilenweise geschrieben und auf eine Vier-Byte-Grenze aufgefüllt.

Diese Einfachheit machte BMP über ein Jahrzehnt lang zum Standard-Bildformat von Windows. Paintbrush, die Windows-Hintergrundbild-Engine, frühe Scanner und unzählige interne Tools verarbeiteten BMP nativ.

Die Dateistruktur

Eine BMP-Datei hat vier Teile, die nacheinander angeordnet sind:

BITMAPFILEHEADER   (14 Bytes)
BITMAPINFOHEADER   (40 Bytes für die klassische Version)
Color Table        (optional, für indizierte Farbmodi)
Pixel Data         (das eigentliche Bild)

BITMAPFILEHEADER (14 Bytes)

Bytes 0-1:   Signatur    "BM" (0x42 0x4D)
Bytes 2-5:   FileSize    (uint32, Little-Endian)
Bytes 6-9:   Reserved    (immer 0)
Bytes 10-13: Offset      (uint32, Offset zu den Pixeldaten vom Dateianfang)

Die Signatur ist nicht immer "BM". Windows unterstützt auch "BA", "CI", "CP", "IC" und "PT" für Cursor- und Icon-Varianten, aber in der Praxis beginnt fast jede BMP-Datei mit "BM".

BITMAPINFOHEADER (40 Bytes, BITMAPINFOHEADER-Typ)

Bytes 0-3:   HeaderSize        (40)
Bytes 4-7:   Width             (int32, Pixel)
Bytes 8-11:  Height            (int32, Pixel; negativ bedeutet Top-Down)
Bytes 12-13: Planes            (1)
Bytes 14-15: BitCount          (1, 4, 8, 16, 24 oder 32)
Bytes 16-19: Compression       (0 = keine, 1 = RLE8, 2 = RLE4, 3 = Bitfields)
Bytes 20-23: ImageSize         (0 wenn unkomprimiert)
Bytes 24-27: XpixelsPerMeter   (physikalische Auflösung)
Bytes 28-31: YpixelsPerMeter   (physikalische Auflösung)
Bytes 32-35: ColorsUsed        (0 bedeutet 2^BitCount)
Bytes 36-39: ColorsImportant   (0 bedeutet alle)

Spätere Windows-Versionen fügten größere Header hinzu — 52, 56, 108 und 124 Bytes — um Alphamasken, Farbräume und ICC-Profile zu unterstützen. Die 40-Byte-Version ist aber immer noch die, der man am häufigsten begegnet.

Höhe bestimmt die Zeilenrichtung

Wenn das Höhenfeld positiv ist, wird das Bild bottom-up gespeichert. Zeile 0 in der Datei ist dann die unterste Zeile des Bildes. Wenn das Höhenfeld negativ ist, wird das Bild top-down gespeichert. Das ist eine der stillen Eigenheiten von BMP — die meisten anderen Formate speichern standardmäßig top-down.

Die Farbtabelle

Bei Farbtiefen von 1, 4 oder 8 verwendet BMP eine indizierte Palette. Jeder Paletteneintrag ist vier Bytes: Blau, Grün, Rot und ein reserviertes Alpha-Byte, das fast immer ignoriert wird. Eine 256-Farben-BMP hat eine 1.024 Byte große Farbtabelle direkt hinter dem Header. Die folgenden Pixeldaten sind keine Farben — sie sind Indizes in diese Tabelle.

Padding in den Pixeldaten

Jede Bildzeile muss ein Vielfaches von vier Bytes lang sein. Ein 24-Bit-Bild, das 5 Pixel breit ist, benötigt 15 Bytes pro Zeile, die auf 16 aufgerundet werden. Diese zusätzlichen Auffüllbytes sind verschwendeter Speicher — ein weiterer kleiner Grund, warum BMP ineffizient ist.

Ein vollständiges Beispiel für eine 2 x 2 24-Bit-unkomprimierte BMP:

Offset 0x00: 42 4D 46 00 00 00 00 00 00 00 36 00 00 00  -- BITMAPFILEHEADER
Offset 0x0E: 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18 00  -- BITMAPINFOHEADER
Offset 0x22: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
Offset 0x32: 00 00 00 00 00 00 00 00
Offset 0x36: FF 00 00 00 FF 00 00 00 FF  -- untere Zeile: rot, grün, blau (mit Padding)
Offset 0x3F: 00 FF FF 00 FF FF 00 00 00  -- obere Zeile: cyan, magenta, gelb (mit Padding)

Das Formatumfeld 1990

BMP erschien nicht im Vakuum. Bis 1990 konkurrierten bereits mehrere Bildformate um Aufmerksamkeit:

FormatKompressionFarbtiefeTransparenzPatentrisikoTypischer Einsatz
GIFLZWmax. 256 Farben1-BitJa (LZW)Web-Grafiken
JPEGDCT + Huffman24-BitKeineMeist neinFotografien
TIFFMehrere optionalbis 48-BitJaOptionalDruck, Scannen
PCXRLEbis 24-BitKeineNeinDOS-Spiele, Cliparts
PICTRLEbis 32-BitJaNeinClassic Mac OS
BMPKeine oder RLEbis 32-BitKeineNeinWindows-Hintergrundbilder, Icons

GIF war bereits der Standard im Web, aber der LZW-Patentschatten machte den kommerziellen Einsatz riskant. JPEG war für Fotografien gedacht und arbeitete mit verlustbehafteter Kompression. TIFF war mächtig, aber überkonstruiert — einen universellen TIFF-Reader zu schreiben, war ein Projekt für sich. PCX verschwand mit DOS.

BMPs Verkaufsargument war Einfachheit. Es war nicht kleiner, schneller oder leistungsfähiger als die anderen. Es war das Format, das Windows ohne zusätzliche Bibliotheken verstand.

Warum BMP funktionierte

BMP hatte in seinem Kontext echte Vorteile:

Keine Dekodierungskomplexität. Eine 24-Bit-unkomprimierte BMP kann gerendert werden, indem man einen Header fester Größe liest und die Pixel direkt in einen Framebuffer kopiert. Keine Huffman-Tabellen, kein DEFLATE-Zustandsautomat, keine progressiven Durchläufe. Das machte es ideal für eingebettete Systeme mit begrenzter CPU-Leistung.

Keine Patentbelastung. Im Gegensatz zu GIFs LZW war BMP-Kompression entweder abwesend oder RLE, beides unbelastet. Das war wichtig für Open-Source-Tools und kommerzielle Software, die Unisys' GIF-Lizenzierung vermeiden wollte.

Direkte Windows-Integration. Die Win32-API hatte LoadBitmap, BitBlt und StretchBlt um DIB-Sektionen herum aufgebaut. Ein Entwickler konnte eine BMP in den Speicher laden und in wenigen Zeilen C auf den Bildschirm blitten.

Vorhersagbarer Speicheraufbau. Da unkomprimierte BMP-Pixel direkt auf den Bildschirmspeicher abbilden, verwendeten Game-Engines und Grafiktools BMP in den 1990ern als Textur-Austauschformat. Man konnte die Datei memory-mappen und den Pixel-Offset als rohen Puffer behandeln.

Wo BMP Schwächen zeigte

BMPs Stärken waren auch seine Schwächen. Das Format kam nicht mit der Zeit.

Keine effektive Kompression. Unkomprimierte BMPs sind riesig. Ein 1920 x 1080 24-Bit-Bild ist 5,93 MB. Dasselbe Bild als JPEG mit Qualität 90 ist etwa 300–500 KB. Als Internetgeschwindigkeit und Speicherkosten zu Begrenzungen wurden, wurde BMP zunehmend unattraktiv.

RLE-Kompression ist schwach. BMP unterstützt RLE8- und RLE4-Lauflängenkodierung, aber RLE hilft nur bei Bildern mit großen einfarbigen Flächen. Fotos und Verläufe komprimieren schlecht. RLE-kodierte BMPs sind in der Praxis selten.

Keine echte Transparenz. Standard-BMP hat keinen Alphakanal. Die 32-Bit-BMP-Variante enthält ein Alpha-Byte, aber viele Tools ignorieren es oder behandeln es als reserviert. Für Web-Grafiken und Game-Sprites machte das BMP gegenüber PNG nutzlos.

Keine Animation, keine Metadaten, kein Farbmanagement. BMP speichert Pixel und sonst kaum etwas. Kein EXIF, keine ICC-Profile im ursprünglichen Header, keine Animationsframes. Als Workflows anspruchsvoller wurden, blieb BMP primitiv.

Bottom-up-Speicherung. Die standardmäßige Bottom-up-Zeilenreihenfolge verwirrt Decoder und verschwendet Zyklen für die Umwandlung. Ein kleines Detail, das ohne Vorteil zusätzlichen Aufwand bedeutet.

Die Formate, die BMP abgelöst haben

BMPs Einschränkungen haben direkt geprägt, was danach kam.

PNG (1996) löste das Transparenz- und Kompressionsproblem. Es bot verlustfreie Kompression, 8-Bit-Alpha und eine einfachere Spezifikation als TIFF. PNG ersetzte BMP fast überall im Web und in plattformübergreifenden Anwendungen.

JPEG (1992) löste das Fotoproblem. Seine DCT-basierte verlustbehaftete Kompression machte Fotos 10–20× kleiner als unkomprimierte BMP. Für Fotos und Bilder mit kontinuierlichen Farbverläufen wurde JPEG zum Standard.

WebP (2010) fügte verlustbehaftete und verlustfreie Modi, Animation und Alpha in einem Container hinzu. Ein verlustfreies WebP ist typischerweise 20–30 % kleiner als PNG, das selbst BMP bei Weitem schlägt.

HEIC/HEIF (2013) brachte HEVC-basierte Kompression für Standbilder. Es erreicht kleinere Dateigrößen als JPEG bei besserer Qualität, unterstützt Alpha und Tiefenkarten und ist inzwischen Standard auf Apple-Geräten. Wenn ein iPhone ein Foto speichert, ist es meist HEIC.

Jedes dieser Formate existiert, weil BMP für einen bestimmten Anwendungsfall nicht mehr gut genug war.

Wo BMP heute noch vorkommt

BMP hat sich in Nischen etabliert, in denen seine Einfachheit die Ineffizienz ausgleicht.

Windows-Interna. Der Windows-Bootbildschirm, ältere Dialoge und einige Systemressourcen verwenden noch BMP. Die Win32-GDI-API erwartet DIB-Daten, und diese Codepfade neu zu schreiben, lohnt Microsoft nicht.

Eingebettete Systeme und Mikrocontroller. Ein kleines LCD an einem Arduino oder STM32 hat weder RAM noch CPU, um PNG zu dekodieren. Eine 16-Bit-unkomprimierte BMP kann mit fast keinem Code direkt in den Framebuffer kopiert werden.

Medizinische und wissenschaftliche Bildgebung. Einige ältere DICOM-Viewer und Laborgeräte exportieren BMP, weil jedes System es öffnen kann. Die Einfachheit des Formats reduziert Interoperabilitätsrisiken — das zählt in regulierten Umgebungen.

Reverse Engineering und Bildung. BMP ist immer noch eines der besten Formate, um die Struktur von Bilddateien zu lehren. Die Header sind klein, das Pixel-Layout offensichtlich, und man kann an einem Nachmittag einen funktionierenden Decoder bauen.

Legacy-Spieleentwicklung. Ältere Game-Engines und Textur-Tools verwendeten BMP als Zwischenformat. Einige Modding-Communities arbeiten immer noch mit BMP-Assets, weil die Tools darauf aufgebaut sind.

BMP anhand der Signatur erkennen

Vertraue nicht der .bmp-Erweiterung. Lies die ersten zwei Bytes.

TypeScript

async function isBmp(file: File): Promise<boolean> {
  const buffer = await file.slice(0, 2).arrayBuffer()
  const bytes = new Uint8Array(buffer)
  return bytes.length === 2 && bytes[0] === 0x42 && bytes[1] === 0x4d
}

Python

def is_bmp(path: str) -> bool:
    with open(path, "rb") as f:
        return f.read(2) == b"BM"

Go

func isBmp(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	defer f.Close()

	buf := make([]byte, 2)
	if _, err := f.Read(buf); err != nil {
		return false
	}
	return bytes.Equal(buf, []byte("BM"))
}

PHP

function isBmp(string $path): bool {
    $header = file_get_contents($path, false, null, 0, 2);
    return $header === "BM";
}

ImageMagick CLI

magick identify -verbose image.bmp | grep "Format:"
# Format: BMP (Microsoft Windows bitmap image)

Oder einfach:

file image.bmp
# image.bmp: PC bitmap, Windows 3.x format, 1920 x 1080 x 24

Die Zukunft von BMP

BMP ist ein abgeschlossenes Format. Die Kernspezifikation hat sich seit der Windows-95-Ära nicht mehr wirklich verändert. Das ist sowohl eine Einschränkung als auch eine Garantie: Eine 1995 geschriebene BMP lässt sich heute noch korrekt öffnen.

Das Format wird keine neuen Funktionen bekommen. Es wird keine bessere Kompression, kein ordentliches Alpha-Handling und keine Animation-Unterstützung erhalten. Niemand investiert in BMP, weil niemand ein besseres BMP braucht. PNG, WebP, AVIF und HEIC haben in jedem Kontext, in dem Effizienz zählt, bereits gewonnen.

Aber BMP bleibt in den Bereichen erhalten, in denen es bereits etabliert ist: Windows-Interna, eingebettete Displays, ältere Medizintechnik und Ausbildung. Es ist nicht elegant und nicht effizient, aber es lässt sich nicht entfernen, weil zu viele Systeme wissen, wie man es liest.

Wenn du ältere BMP-Dateien hast, die auf modernen Geräten nutzbar sein sollen, lohnt sich eine Konvertierung. Für Fotos reduziert die Umwandlung in JPEG oder HEIC den Speicherbedarf deutlich. Für Grafiken mit Transparenz sind PNG oder WebP die bessere Wahl. Und wenn du Dateien aus dem Apple-Ökosystem weitergeben willst, ist die Konvertierung von HEIC in ein universell lesbares Format der erste Schritt.

Unser HEIC-to-JPG-Konverter arbeitet komplett im Browser — die Datei verlässt niemals dein Gerät. Für verlustfreie Ausgabe mit Transparenz bietet sich HEIC to PNG an. Wer weboptimierte Dateien braucht, bekommt mit HEIC to WebP kleinere Dateien mit breiter Browser-Unterstützung.

BMP hat der Branche eine wertvolle Lektion erteilt: Ein Format muss nicht das beste sein, um überall zu sein. Es muss nur einfach genug sein, dass es jeder implementiert, und fest genug verankert, dass sich niemand die Mühe macht, es durch etwas anderes zu ersetzen.

Mehr Blog-Posts zum Lesen