{"record":{"id":"b962ee9b60cbeedc","repo":"PHPOffice/PhpSpreadsheet","slug":"unable-to-create-image-from-filename","errorCode":null,"errorMessage":"Unable to create image from $filename","messagePattern":"Unable to create image from \\$filename","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Writer\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Writer/Xls.php","lineNumber":449,"sourceCode":"    }\n\n    private static int $two = 2; // phpstan silliness\n\n    private function processDrawing(BstoreContainer &$bstoreContainer, Drawing $drawing): void\n    {\n        $blipType = 0;\n        $blipData = '';\n        $filename = $drawing->getPath();\n\n        $imageSize = getimagesize($filename);\n        $imageFormat = empty($imageSize) ? 0 : ($imageSize[self::$two] ?? 0);\n\n        switch ($imageFormat) {\n            case 1: // GIF, not supported by BIFF8, we convert to PNG\n                $blipType = BSE::BLIPTYPE_PNG;\n                $newImage = @imagecreatefromgif($filename);\n                if ($newImage === false) {\n                    throw new Exception(\"Unable to create image from $filename\");\n                }\n                ob_start();\n                imagepng($newImage);\n                $blipData = ob_get_contents();\n                ob_end_clean();\n\n                break;\n            case 2: // JPEG\n                $blipType = BSE::BLIPTYPE_JPEG;\n                $blipData = file_get_contents($filename);\n\n                break;\n            case 3: // PNG\n                $blipType = BSE::BLIPTYPE_PNG;\n                $blipData = file_get_contents($filename);\n\n                break;\n            case 6: // Windows DIB (BMP), we convert to PNG","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Writer/Xls.php#L431-L467","documentation":"BIFF8 (Xls) has no native GIF blip type, so the Xls writer converts every GIF drawing to PNG using GD's imagecreatefromgif() before embedding it. If that function returns false - corrupt/truncated GIF, unreadable path, or a GD build without GIF read support - this Exception is thrown while writing the workbook.","triggerScenarios":"A worksheet drawing (setPath() to a .gif) whose file is corrupt or partially uploaded; the path points at a stream wrapper GD cannot seek/read; PHP's GD extension compiled without --with-gif read support, making imagecreatefromgif() undefined or failing.","commonSituations":"User-uploaded images validated only by file extension; images fetched from object stores (s3://) without a local copy; truncated uploads; minimal Alpine/Debian container images where GD lacks format support.","solutions":["Validate images before attaching: getimagesize() must succeed and report IMAGETYPE_GIF, and function_exists('imagecreatefromgif') must be true.","Re-encode GIFs to PNG server-side before adding the drawing - Xls embeds PNGs natively with no conversion step.","Reject or quarantine unreadable uploads at ingestion time instead of at export time.","Ensure GD is installed with GIF support (php -i | grep GD) in the deployment image."],"exampleFix":"// before\n$drawing = new \\PhpOffice\\PhpSpreadsheet\\Worksheet\\Drawing();\n$drawing->setPath($uploadedPath); // corrupt .gif => throws during save()\n\n// after\n$size = @getimagesize($uploadedPath);\nif ($size === false || $size[2] !== IMAGETYPE_GIF || !function_exists('imagecreatefromgif')) {\n    $uploadedPath = reencodeAsPng($uploadedPath); // or reject the file\n}\n$drawing->setPath($uploadedPath);","handlingStrategy":"validation","validationCode":"/** @param Worksheet[] $sheets */\nfunction assertImagesReadableForXls(array $sheets): void\n{\n    foreach ($sheets as $sheet) {\n        foreach ($sheet->getDrawingCollection() as $drawing) {\n            $path = $drawing->getPath();\n            $info = @getimagesize($path);\n            if ($info === false) {\n                throw new RuntimeException(\"Unreadable image: $path\");\n            }\n            if ($info[2] === IMAGETYPE_GIF && !function_exists('imagecreatefromgif')) {\n                throw new RuntimeException('GD lacks GIF support; convert ' . $path . ' to PNG');\n            }\n        }\n    }\n}\nassertImagesReadableForXls($spreadsheet->getAllSheets());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify uploads with getimagesize() (content sniffing), not extension or MIME header.","Re-encode all raster images to PNG/PNG-compatible formats at ingestion so no runtime GD conversion is needed.","Ensure local copies of remote images exist before export; GD needs seekable streams.","Include GD format support in your image build's smoke test (php -r 'var_dump(function_exists(\"imagecreatefromgif\"));')."],"tags":["xls","image","gd","gif","drawing","biff8"],"backgroundTag":"image-decode-failed","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}