{"record":{"id":"2e3805fbc212a9c6","repo":"PHPOffice/PhpSpreadsheet","slug":"value-cannot-be-converted-to-an-image","errorCode":null,"errorMessage":"Value cannot be converted to an image","messagePattern":"Value cannot be converted to an image","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/MemoryDrawing.php","lineNumber":143,"sourceCode":"     * @throws Exception\n     */\n    public static function fromStream($imageStream): self\n    {\n        $streamValue = stream_get_contents($imageStream);\n\n        return self::fromString($streamValue);\n    }\n\n    /**\n     * @param string $imageString String data to be converted to a Memory Drawing\n     *\n     * @throws Exception\n     */\n    public static function fromString(string $imageString): self\n    {\n        $gdImage = @imagecreatefromstring($imageString);\n        if ($gdImage === false) {\n            throw new Exception('Value cannot be converted to an image');\n        }\n\n        $mimeType = self::identifyMimeType($imageString);\n        if (imageistruecolor($gdImage) || imagecolortransparent($gdImage) >= 0) {\n            imagesavealpha($gdImage, true);\n        }\n        $renderingFunction = self::identifyRenderingFunction($mimeType);\n\n        $drawing = new self();\n        $drawing->setImageResource($gdImage);\n        $drawing->setRenderingFunction($renderingFunction);\n        $drawing->setMimeType($mimeType);\n\n        return $drawing;\n    }\n\n    /** @return callable-string */\n    private static function identifyRenderingFunction(string $mimeType): string","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php#L125-L161","documentation":"MemoryDrawing::fromString() turns raw binary into a GD resource via @imagecreatefromstring(); when GD returns false, the string is not a decodable image in any format your GD build supports, and the exception is thrown. Common culprits are base64 payloads that were not decoded (or double-encoded) and formats like WEBP/AVIF on a GD compiled without them.","triggerScenarios":"fromString($base64) where the value is still the base64 text or still has the 'data:image/png;base64,' prefix; binary from a truncated download; WEBP bytes on a GD build without webp support.","commonSituations":"Images pasted from HTML editors or received from APIs as data URIs; reading embedded media from untrusted XLSX files; forgetting base64_decode() or applying it twice; environment differences in GD format support.","solutions":["Strip any data-URI prefix and base64_decode() the payload before calling fromString().","Pre-validate with getimagesizefromstring($binary) — it returns false for undecodable data and reports the type otherwise.","Check gd_info() for the formats your inputs need and convert unsupported formats server-side."],"exampleFix":"// before\n$drawing = MemoryDrawing::fromString($base64FromApi); // encoded string -> throws\n\n// after\n$binary = str_starts_with($base64FromApi, 'data:')\n    ? base64_decode(substr($base64FromApi, strpos($base64FromApi, ',') + 1), true)\n    : base64_decode($base64FromApi, true);\nif ($binary === false || getimagesizefromstring($binary) === false) {\n    throw new InvalidArgumentException('payload is not a decodable image');\n}\n$drawing = MemoryDrawing::fromString($binary);","handlingStrategy":"validation","validationCode":"$binary = $data;\nif (str_starts_with($data, 'data:')) {\n    $binary = base64_decode(substr($data, strpos($data, ',') + 1), true);\n}\nif ($binary === false || getimagesizefromstring($binary) === false) {\n    throw new InvalidArgumentException('payload is not a decodable image');\n}\n$drawing = MemoryDrawing::fromString($binary);","typeGuard":"function isDecodableImageString(string $bytes): bool\n{\n    return getimagesizefromstring($bytes) !== false;\n}","tryCatchPattern":"try {\n    $drawing = MemoryDrawing::fromString($payload);\n} catch (PhpSpreadsheetException $e) {\n    // payload was not decodable: log, skip the image, or request a re-upload\n}","preventionTips":["Strip data: URI prefixes and base64_decode exactly once","Pre-check every payload with getimagesizefromstring() before conversion","When inputs may be WEBP/AVIF, confirm the running GD supports them via gd_info()"],"tags":["php","phpspreadsheet","gd","base64","image-decode","memory-drawing"],"backgroundTag":"invalid-image-data","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}