Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains und...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte Internetdienstleistungen...
https://www.Artfiles.de
 
 
 

PHP imagebmp() Function: Bilder als BMP speichern

Sie befinden sich: Home > Php Tutorial > PHP imagebmp() Function: Bi...

PHP imagebmp() Function: Bilder als BMP speichern
Veröffentlicht am:
10.10.2026
Hits / Besucher:
12
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Ein Etikettendrucker an der Packstraße nimmt nur Bitmaps entgegen, das Bedienpanel einer älteren Maschine ebenso. Mit beiden lässt sich nicht verhandeln, und ein Konvertierungswerkzeug auf dem Server nachzuinstallieren ist genau die Abhängigkeit, die man sich in einem PHP-Projekt sparen will. PHP kann das Format seit Version 7.2 selbst schreiben, und PHP imagebmp ist die eine Zeile, die dafür nötig ist. Wer mit GD noch nie gearbeitet hat, findet den Einstieg im Tutorial zur GD-Bibliothek. Gebraucht wird davon nur der letzte Schritt: ein fertiges Bild landet als Datei auf der Platte.

Illustration zum Tutorial: PHP imagebmp() Function: Bilder als BMP speichern

Dieselbe Grafik wiegt als Bitmap ein Vielfaches ihrer PNG-Fassung, und daran lässt sich wenig ändern: PHP imagebmp() schreibt jedes Pixel einzeln aus. Wie groß der Abstand zu PNG ausfällt, steht weiter unten als gemessene Zahl.

Was PHP imagebmp() aus einem GD-Bild macht

Die Funktion nimmt ein fertiges Bild und legt es als Windows Bitmap ab, wahlweise in eine Datei oder direkt auf die Ausgabe. Sie erzeugt kein neues Bild, sie verändert das übergebene nicht, und sie gibt nur einen Wahrheitswert zurück. Diesen Wert sollte man ausnahmsweise auswerten: Zeigt der Pfad in ein Verzeichnis, das es nicht gibt, kommt false zurück, und das Skript läuft ansonsten klaglos weiter.

<?php

$bild = imagecreatetruecolor(400, 300);
$grund = imagecolorallocate($bild, 30, 30, 40);
$rot = imagecolorallocate($bild, 200, 60, 60);
imagefilledrectangle($bild, 0, 0, 399, 299, $grund);
imagefilledrectangle($bild, 20, 20, 180, 120, $rot);

if (!imagebmp($bild, 'etikett.bmp')) {
throw new RuntimeException('BMP fehlgeschlagen');
}
imagedestroy($bild);

Mehr braucht es nicht, und genau darin liegt der Reiz von PHP imagebmp(). Gespeichert wird eine Datei von 360.054 Byte, die jedes Windows-Werkzeug und jeder Etikettentreiber ohne Nachfrage öffnet. Wie hoch sie ausfällt und ob sich daran etwas ändern lässt, entscheidet allein die Farbtiefe des Bildes.

Syntax, Parameter und Rückgabewert im Original

<?php

imagebmp(
GdImage $image,
resource|string|null $file = null,
bool $compressed = true
): bool

/* writes a GD image as a Windows bitmap,
available since PHP 7.2

image: the image to write; it is left
unchanged by the call
file: a path, an already open stream, or
null to send the data to the output
compressed: switches on RLE8 run-length
encoding, which the BMP format only allows
for 8-bit palette images; the default is
true, not false

returns true on success, false when the
target file cannot be written */

Zwei Angaben aus diesem Block bestimmen den Rest. Erstens ist der zweite Parameter voreingestellt auf null, und das ist kein Fehlerfall, sondern die Ausgabe an den Browser. Zweitens steht der dritte Parameter auf true. Er ist also gesetzt, ohne dass man ihn schreibt. Wer PHP imagebmp() ohne dritten Parameter aufruft, verlangt damit bereits Kompression. Ob er sie bekommt, entscheidet allein der Bildtyp, und genau daran scheitern die meisten Erwartungen an diese Funktion.

Der Parameter $file: Datei, Stream oder Ausgabe an den Browser

Lässt man den Dateinamen weg, wandert die Bitmap in den Ausgabepuffer. Davor gehört der passende MIME-Typ, sonst zeigt der Browser Binärzeichen als Text an. Und es darf vorher wirklich nichts ausgegeben worden sein: Steht auch nur ein Leerzeichen vor dem header(), ist die Datei kaputt.

<?php

$bild = imagecreatetruecolor(4, 4);

header('Content-Type: image/bmp');
header('Content-Disposition: inline');
imagebmp($bild);
imagedestroy($bild);

Wie viel PHP imagebmp() dabei über die Leitung schickt, lässt sich mit der Ausgabepufferung nachmessen. Ein Bild von vier mal vier Pixeln ergibt 102 Byte, und die ersten beiden davon sind die Signatur BM, an der jedes Programm eine Bitmap erkennt. 54 Byte davon sind Dateikopf, der Rest sind Bilddaten samt Zeilenauffüllung.

<?php

ob_start();
imagebmp($bild);
$roh = (string) ob_get_clean();

echo strlen($roh), ' Byte, ', substr($roh, 0, 2);
/* 102 Byte, BM */

Der Parameter compressed und warum er meistens nichts tut

Das folgende Skript speichert dasselbe Truecolor-Bild zweimal, einmal ausdrücklich ohne und einmal ausdrücklich mit Kompression, und vergleicht beide Dateien nicht nur nach Größe, sondern über ihre Prüfsumme.

<?php

imagebmp($bild, 'ohne.bmp', false);
imagebmp($bild, 'mit.bmp', true);

printf(
"ohne %d %s\nmit %d %s\n",
filesize('ohne.bmp'), md5_file('ohne.bmp'),
filesize('mit.bmp'), md5_file('mit.bmp')
);
/* ohne 360054 3c814af7b8d8358036b2f5f94ef071a8
mit 360054 3c814af7b8d8358036b2f5f94ef071a8 */

Die beiden Dateien sind nicht nur gleich groß, sie sind byteweise identisch. Das Kompressionsfeld im Dateikopf steht in beiden Fällen auf 0. Eine Warnung gibt es nicht, einen Fehler ebenso wenig, und der Rückgabewert ist beide Male true. Wer an dieser Stelle einen Fehler im eigenen Code sucht, sucht lange, denn PHP imagebmp() hat sich genau so verhalten, wie es soll.

Der Grund liegt nicht an der Funktion, sondern am Format selbst. BMP kennt die Lauf­längen­kodierung RLE8 ausschließlich für Bilder mit 8 Bit Farbtiefe, also für Palettenbilder. Ein Truecolor-Bild landet immer mit 24 Bit in der Datei, und dafür ist im Format schlicht keine Kompression vorgesehen. Legt man dieselbe Grafik mit imagecreate() als Palettenbild an, kippt das Ergebnis vollständig.

<?php

$bild = imagecreate(400, 300);
$grund = imagecolorallocate($bild, 30, 30, 40);
$rot = imagecolorallocate($bild, 200, 60, 60);
imagefilledrectangle($bild, 20, 20, 180, 120, $rot);

imagebmp($bild, 'pal_ohne.bmp', false); /* 120062 */
imagebmp($bild, 'pal_mit.bmp', true); /* 3266 */
Bild, 400 mal 300 compressed false compressed true Kompressionsfeld
Truecolor, 24 Bit 360.054 Byte 360.054 Byte 0 und 0
Palette, 8 Bit, große Flächen 120.062 Byte 3.266 Byte 0 und 1
Palette, 8 Bit, reines Rauschen 121.078 Byte 124.780 Byte 0 und 1

Die dritte Zeile ist die Warnung an alle, die RLE8 jetzt pauschal einschalten wollen. Bei einem Palettenbild mit zufälligem Farbindex je Pixel macht die Kodierung die Datei um gut drei Prozent größer, weil jede Bildzeile in lauter Einzelstücke zerfällt und jedes davon seinen eigenen Vorspann bekommt. Lauf­längen­kodierung lohnt sich bei ruhigen Flächen, nicht bei unruhigen Bildern.

Wer ein Truecolor-Bild hat und trotzdem eine kleine Datei braucht, wandelt es vorher um. imagetruecolortopalette($bild, false, 256) senkt die Farbzahl auf höchstens 256 und macht damit den Weg zu RLE8 frei; im Beispiel oben landet die Datei danach bei denselben 3.266 Byte. Das kostet Farben, und bei Fotos oder Verläufen sieht man das sofort. Bei Strichzeichnungen, Symbolen und Etiketten fällt es nicht auf. Welche Farbtiefe tatsächlich in der Datei steht, verrät der Dateikopf an den Byte-Positionen 28 und 30.

<?php

$roh = (string) file_get_contents('pal_mit.bmp');
$bits = unpack('v', substr($roh, 28, 2))[1];
$komp = unpack('V', substr($roh, 30, 4))[1];

echo $bits, ' Bit, Kompression ', $komp;
/* 8 Bit, Kompression 1 */

Wie groß wird die BMP-Datei?

Bei einer unkomprimierten Bitmap lässt sich die Dateigröße vorher ausrechnen, und zwar auf das Byte genau. Der Dateikopf belegt 54 Byte. Danach folgt je Bildzeile ein Block, der auf ein Vielfaches von vier Byte aufgefüllt wird. Bei 24 Bit Farbtiefe gilt also zeile = ceil(breite * 3 / 4) * 4 und darauf 54 + hoehe * zeile.

<?php

function bmpGroesse(int $breite, int $hoehe): int
{
$zeile = (int) (ceil($breite * 3 / 4) * 4);

return 54 + $hoehe * $zeile;
}

foreach ([100, 101, 102, 103] as $b) {
echo $b, ': ', bmpGroesse($b, 10), "\n";
}
/* 100: 3054 101: 3094
102: 3134 103: 3174 */

Gegen die von PHP imagebmp() wirklich geschriebenen Dateien geprüft stimmt jede dieser vier Zahlen. Sie zeigen auch, warum eine Breite von 103 Pixeln denselben Platz kostet wie 104: Die Auffüllung rundet nach oben. Praktisch wichtig wird die Formel bei großen Bildern. Ein Foto mit 4000 mal 3000 Pixeln belegt als Bitmap 36.000.054 Byte, also rund 34 MiB. Wer das über den Ausgabepuffer schickt, reißt das memory_limit, bevor das erste Byte beim Browser ankommt. Der wirksamste Hebel dagegen ist nicht die Kompression, sondern kleinere Maße; wie das sauber geht, zeigt das Tutorial zum Skalieren und Erzeugen von Thumbnails.

flowchart TD
    A[Bild anlegen] --> B{Truecolor?}
    B -- ja --> C[24 Bit]
    C --> D[compressed wirkt nicht]
    B -- nein --> E[8 Bit Palette]
    E --> F{Große Flächen?}
    F -- ja --> G[RLE spart viel]
    F -- nein --> H[RLE wird größer]
    D --> I[BMP schreiben]
    G --> I
    H --> I

BMP gegen PNG, JPEG und WebP

Damit ein Formatvergleich etwas taugt, muss er an derselben Grafik laufen. Die folgenden Zeilen schreiben ein Balkendiagramm im Serienformat dieser Seite, also 550 mal 310 Pixel, in allen vier Formaten und lesen die Größen aus.

<?php

imagebmp($bild, 'v.bmp', false);
imagepng($bild, 'v.png');
imagejpeg($bild, 'v.jpg', 85);
imagewebp($bild, 'v.webp');

foreach (['bmp', 'png', 'jpg', 'webp'] as $e) {
printf("%-5s %8d\n", $e, filesize("v.$e"));
}
Format Dateigröße Verhältnis zu PNG wofür geeignet
BMP 512.174 Byte 387-fach Gegenstellen, die nur Bitmaps lesen
PNG 1.323 Byte 1-fach Grafiken, Text im Bild, Transparenz
JPEG, Qualität 85 9.522 Byte 7-fach Fotos, hier klar die falsche Wahl
WebP 1.166 Byte 0,9-fach dasselbe wie PNG, etwas kleiner

Das 387-fache ist keine Rundung nach oben, sondern der gemessene Quotient aus den beiden Dateien, die PHP imagebmp() und imagepng() hier erzeugt haben. Bei einer Grafik mit großen einfarbigen Flächen spielt PNG seine Stärke voll aus, während die Bitmap jedes einzelne Pixel ausschreibt. Trotzdem stimmt der Satz, BMP sei immer größer als PNG, nicht. Füllt man ein Bild derselben Größe mit reinem Farbrauschen, liegt die Bitmap bei 512.174 Byte und das PNG bei 512.798 Byte. Ohne jede Struktur bleibt PNG nichts zu komprimieren, und sein Verwaltungsaufwand kippt das Ergebnis. Der Fall ist konstruiert, aber er zeigt, woher der Unterschied sonst kommt.

Wann BMP die richtige Wahl ist und wann nicht

Die ehrliche Antwort lautet meistens: gar nicht. PHP imagebmp() gehört in ein Projekt, wenn eine Gegenstelle das Format vorschreibt, und sonst nirgends. In der Praxis sind das vier Fälle.

  • Altsysteme unter Windows, die Bilder über die Zwischenablage oder über einen festen Ordner einlesen.
  • Etiketten- und Bondrucker mit eigenem Treiber, der nur Bitmaps kennt.
  • Bedien- und Anzeigepanels an Maschinen, oft mit fest verdrahteter Farbtiefe.
  • Prüfwerkzeuge, die zwei Bilder byteweise vergleichen und deshalb ein Format ohne Kompression brauchen.

Kein einziger dieser Fälle ist eine Webseite. Für alles, was im Browser landet, ist PNG die bessere Wahl: ebenso verlustfrei, dazu transparenzfähig und um Größen­ordnungen kleiner. Noch eine Randnotiz zur Gegenrichtung, damit niemand mit offener Frage aus dem Text geht: imagecreatefrombmp() liest eine Bitmap wieder in ein GD-Bild ein, der Umlauf bleibt dabei verlustfrei, und auch die RLE-komprimierte Fassung wird korrekt erkannt. Wie GD Bilder aus vorhandenen Daten aufbaut, behandelt das Tutorial zu imagecreatefromstring().

Fazit

Der dritte Parameter von PHP imagebmp() steht auf true und bewirkt bei Truecolor-Bildern nachweislich nichts. RLE8 gibt es nur für 8-Bit-Palettenbilder, dort dafür mit großer Wirkung, und bei unruhigen Motiven bläht es die Datei sogar auf. Die Größe einer unkomprimierten Bitmap steht vorher fest und lässt sich mit zwei Rechenschritten bestimmen. Wer diese drei Punkte kennt, setzt PHP imagebmp() dort ein, wo es hingehört, und greift überall sonst zu PNG.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.