PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception
$bitmap: only 1 plane supported in bitmap image.\n
Error message
$bitmap: only 1 plane supported in bitmap image.\n
What it means
The second half of the planes/bitcount check: processBitmap() requires the BMP header's planes field to equal exactly 1. Well-formed BMPs always declare 1 plane, so a different value means a malformed or exotic header, and the write is rejected.
Source
Thrown at src/PhpSpreadsheet/Writer/Xls/Worksheet.php:2520
$width = $width_and_height[1];
/** @var int */
$height = $width_and_height[2];
$data = substr($data, 8);
if ($width > 0xFFFF) {
throw new WriterException("$bitmap: largest image width supported is 65k.\n");
}
if ($height > 0xFFFF) {
throw new WriterException("$bitmap: largest image height supported is 65k.\n");
}
// Read and remove the bitmap planes and bpp data. Verify them.
$planes_and_bitcount = unpack('v2', substr($data, 0, 4));
$data = substr($data, 4);
if ($planes_and_bitcount === false || $planes_and_bitcount[2] != 24) { // Bitcount
throw new WriterException("$bitmap isn't a 24bit true color bitmap.\n");
}
if ($planes_and_bitcount[1] != 1) {
throw new WriterException("$bitmap: only 1 plane supported in bitmap image.\n");
}
// Read and remove the bitmap compression. Verify compression.
$compression = unpack('Vcomp', substr($data, 0, 4));
$data = substr($data, 4);
if ($compression === false || $compression['comp'] != 0) {
throw new WriterException("$bitmap: compression not supported in bitmap image.\n");
}
// Remove bitmap data: data size, hres, vres, colours, imp. colours.
$data = substr($data, 20);
// Add the BITMAPCOREHEADER data
$header = pack('Vvvvv', 0x000C, $width, $height, 0x01, 0x18);
$data = $header . $data;
return [$width, $height, $size, $data];View on GitHub (pinned to 65b080eef4)
Solutions
- Re-export the bitmap with a reputable tool (GD, Photoshop, GIMP)
- Validate the full header (planes == 1, bitcount == 24, compression == 0) before insertion
- Fall back to PNG/JPEG via the Drawing API
Defensive patterns
Strategy: validation
Validate before calling
$hdr = unpack('A2ident/vplanes/vbits', (string) file_get_contents($path, false, null, 0, 26));
if ($hdr === false || $hdr['ident'] !== 'BM' || $hdr['planes'] !== 1) {
throw new InvalidArgumentException("Malformed BMP header in $path (planes != 1)");
}
$worksheetWriter->insertBitmap($row, $col, $path); Prevention
- Validate the full BMP header (magic, planes, bitcount, compression) in one pass before insertion
- Regenerate suspicious files with a standard imaging library rather than patching bytes
When it happens
Trigger: insertBitmap() with a hand-crafted or corrupted BMP whose biPlanes field is 0, 2, or higher; files produced by broken generators.
Common situations: Binary fixtures edited by hand; output of buggy third-party conversion tools; byte-level corruption.
Related errors
- File doesn't seem to be an OLE container.
- The filename $filename is not recognised as an OLE file
- Couldn't import $bitmap
- $bitmap doesn't contain enough data.\n
- $bitmap doesn't appear to be a valid bitmap image.\n
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/b1e5e9e049f69ed1.
Report an issue: GitHub.