{"record":{"id":"92bc62d62a9b5832","repo":"PHPOffice/PhpSpreadsheet","slug":"unsupported-image-type-in-comment-background-supp-92bc62","errorCode":null,"errorMessage":"Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.","messagePattern":"Unsupported image type in comment background\\. Supported types: PNG, JPEG, BMP, GIF\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/Drawing.php","lineNumber":76,"sourceCode":"     * Get Extension.\n     */\n    public function getExtension(): string\n    {\n        if (Preg::isMatch('~^data:image/([^;]+);base64,~', $this->path, $matches)) {\n            return $matches[1];\n        }\n        $exploded = explode('.', basename($this->path));\n\n        return $exploded[count($exploded) - 1];\n    }\n\n    /**\n     * Get full filepath to store drawing in zip archive.\n     */\n    public function getMediaFilename(): string\n    {\n        if (!array_key_exists($this->type, self::IMAGE_TYPES_CONVERTION_MAP)) {\n            throw new PhpSpreadsheetException('Unsupported image type in comment background. Supported types: PNG, JPEG, BMP, GIF.');\n        }\n\n        return sprintf('image%d%s', $this->getImageIndex(), $this->getImageFileExtensionForSave());\n    }\n\n    /**\n     * Get Path.\n     */\n    public function getPath(): string\n    {\n        return $this->path;\n    }\n\n    /**\n     * Set Path.\n     *\n     * @param string $path File path\n     * @param bool $verifyFile Verify file","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/Drawing.php#L58-L94","documentation":"When the Xlsx writer stores a Drawing's image in xl/media it builds the entry name in getMediaFilename(), which requires the image's GD type constant to be a key of Drawing::IMAGE_TYPES_CONVERTION_MAP — only GIF, JPEG, PNG and BMP are listed (GIF/BMP are converted to PNG). The type is detected from the file's real bytes via getimagesize() in setSizesAndType(); the default is IMAGETYPE_UNKNOWN, which also fails the check. The 'comment background' wording is historical — the guard applies to every drawing you attach.","triggerScenarios":"$drawing->setPath('logo.webp') followed by $writer->save('out.xlsx'); TIFF, AVIF, SVG or ICO images; a file renamed to .png whose content is WEBP; EMF/WMF clip-art that passes the mime check but whose type GD cannot detect.","commonSituations":"Images from modern tooling (WEBP is many converters' default), CDN-served WEBP variants, SVG logos for headers, uploads accepted by extension whitelist; the exception surfaces inside save(), far away from the setPath() call.","solutions":["Convert the image to a supported format before attaching it: $img = imagecreatefromwebp($path); imagepng($img, $tmp); $drawing->setPath($tmp);","Or render to a MemoryDrawing::fromString(...) after converting, so the writer always receives PNG/JPEG/GIF/BMP bytes.","Reject or transcode uploads at ingestion when getimagesize()[2] is not IMAGETYPE_PNG/JPEG/GIF/BMP."],"exampleFix":"// before\n$drawing = new Drawing();\n$drawing->setPath('/uploads/logo.webp'); // ok at set time, writer throws later\n\n// after\n$src = imagecreatefromwebp('/uploads/logo.webp');\nimagepng($src, '/tmp/logo.png');\n$drawing->setPath('/tmp/logo.png');","handlingStrategy":"type-guard","validationCode":"$info = @getimagesize($imagePath);\nif ($info === false || !in_array($info[2], [IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP], true)) {\n    $src = imagecreatefromstring(file_get_contents($imagePath));\n    imagepng($src, $imagePath .= '.png'); // transcode to PNG\n}\n$drawing->setPath($imagePath);","typeGuard":"function isSupportedDrawingImage(string $path): bool\n{\n    $info = @getimagesize($path);\n    return $info !== false\n        && in_array($info[2], [IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_BMP], true);\n}","tryCatchPattern":"try {\n    $writer->save($file);\n} catch (PhpSpreadsheetException $e) {\n    if (str_contains($e->getMessage(), 'Unsupported image type')) {\n        // find the offending drawing, transcode it to PNG, then re-save\n    }\n}","preventionTips":["Convert uploads to PNG/JPEG at ingestion; do not trust file extensions","The type is read from the real bytes by getimagesize(), so a renamed .webp still throws","The error surfaces at save() time, far from setPath() — validate as soon as the image arrives"],"tags":["php","phpspreadsheet","image","webp","unsupported-format","xlsx-writer"],"backgroundTag":"unsupported-image-format","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}