PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception

Unable to create image from $filename

Error message

Unable to create image from $filename

What it means

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.

Source

Thrown at src/PhpSpreadsheet/Writer/Xls.php:449

    }

    private static int $two = 2; // phpstan silliness

    private function processDrawing(BstoreContainer &$bstoreContainer, Drawing $drawing): void
    {
        $blipType = 0;
        $blipData = '';
        $filename = $drawing->getPath();

        $imageSize = getimagesize($filename);
        $imageFormat = empty($imageSize) ? 0 : ($imageSize[self::$two] ?? 0);

        switch ($imageFormat) {
            case 1: // GIF, not supported by BIFF8, we convert to PNG
                $blipType = BSE::BLIPTYPE_PNG;
                $newImage = @imagecreatefromgif($filename);
                if ($newImage === false) {
                    throw new Exception("Unable to create image from $filename");
                }
                ob_start();
                imagepng($newImage);
                $blipData = ob_get_contents();
                ob_end_clean();

                break;
            case 2: // JPEG
                $blipType = BSE::BLIPTYPE_JPEG;
                $blipData = file_get_contents($filename);

                break;
            case 3: // PNG
                $blipType = BSE::BLIPTYPE_PNG;
                $blipData = file_get_contents($filename);

                break;
            case 6: // Windows DIB (BMP), we convert to PNG

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Validate images before attaching: getimagesize() must succeed and report IMAGETYPE_GIF, and function_exists('imagecreatefromgif') must be true.
  2. Re-encode GIFs to PNG server-side before adding the drawing - Xls embeds PNGs natively with no conversion step.
  3. Reject or quarantine unreadable uploads at ingestion time instead of at export time.
  4. Ensure GD is installed with GIF support (php -i | grep GD) in the deployment image.

Example fix

// before
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing->setPath($uploadedPath); // corrupt .gif => throws during save()

// after
$size = @getimagesize($uploadedPath);
if ($size === false || $size[2] !== IMAGETYPE_GIF || !function_exists('imagecreatefromgif')) {
    $uploadedPath = reencodeAsPng($uploadedPath); // or reject the file
}
$drawing->setPath($uploadedPath);
Defensive patterns

Strategy: validation

Validate before calling

/** @param Worksheet[] $sheets */
function assertImagesReadableForXls(array $sheets): void
{
    foreach ($sheets as $sheet) {
        foreach ($sheet->getDrawingCollection() as $drawing) {
            $path = $drawing->getPath();
            $info = @getimagesize($path);
            if ($info === false) {
                throw new RuntimeException("Unreadable image: $path");
            }
            if ($info[2] === IMAGETYPE_GIF && !function_exists('imagecreatefromgif')) {
                throw new RuntimeException('GD lacks GIF support; convert ' . $path . ' to PNG');
            }
        }
    }
}
assertImagesReadableForXls($spreadsheet->getAllSheets());

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/b962ee9b60cbeedc. Report an issue: GitHub.