09/27/2026

Convert WebP to JPG or PNG in PHP

Load the file with imagecreatefromwebp(), then save it with imagejpeg(), or with imagepng() if you need to keep transparency. The step people miss: JPEG has no alpha channel, so paint the image onto a white canvas first, or every transparent pixel comes out black.

<?php
function webpToJpeg(string $source, string $target, int $quality = 85): void
{
    $webp = imagecreatefromwebp($source);
    if ($webp === false) {
        throw new RuntimeException("Cannot read $source (missing, corrupt or animated).");
    }

    // JPEG has no alpha channel, so paint onto white first.
    $width  = imagesx($webp);
    $height = imagesy($webp);
    $canvas = imagecreatetruecolor($width, $height);
    imagefill($canvas, 0, 0, imagecolorallocate($canvas, 255, 255, 255));
    imagecopy($canvas, $webp, 0, 0, 0, 0, $width, $height);

    imagejpeg($canvas, $target, $quality);
    clearstatcache();
    if (!is_file($target) || filesize($target) === 0) {
        throw new RuntimeException("Nothing was written to $target.");
    }
}

function webpToPng(string $source, string $target): void
{
    $webp = imagecreatefromwebp($source);
    if ($webp === false) {
        throw new RuntimeException("Cannot read $source (missing, corrupt or animated).");
    }
    imagesavealpha($webp, true);
    imagepng($webp, $target);
}

webpToJpeg('photo.webp', 'photo.jpg');
webpToPng('photo.webp', 'photo.png');

For a whole folder:

foreach (glob('*.webp') as $file) {
    webpToJpeg($file, substr($file, 0, -5) . '.jpg');
}

You need PHP's GD extension built with WebP support. This prints bool(true) when it is:

php -r "var_dump(gd_info()['WebP Support'] ?? false);"

Why transparent areas turn black

imagecreatefromwebp() keeps the WebP's alpha channel, and imagejpeg() can't store one, so it drops the alpha and keeps whatever color sits underneath. I tested with a 200x100 WebP, half red and half transparent. Saved straight to JPEG, the transparent half came out black, rgb(0,0,0). Through the white canvas it came out rgb(255,255,255). Change the fill color if your page background isn't white.

PNG keeps alpha, so webpToPng() needs no canvas. On PHP 8.5 the PNG kept its transparency even without imagesavealpha(); the call is there so you don't depend on that.

Two things that fail

The same page gives the quality range as 0 to 100, with the default of -1 meaning about 75. 85 is a sensible middle.

How to verify

php -r "print_r(getimagesize('photo.jpg'));"

mime should read image/jpeg, and the width and height should match the source. Going the other way, PNG or JPEG to WebP, is this PHP script.

Questions this raises

Why does my converted JPG have a black background?

The WebP had transparent pixels and JPEG can't store transparency, so GD keeps the hidden color underneath, usually black. Copy the image onto a canvas filled with white, or your page color, before calling imagejpeg().

Can PHP convert an animated WebP?

Not with GD. PHP's manual says imagecreatefromwebp() can't read animated WebP files, and it returns false for them.

What JPEG quality should I use?

imagejpeg() takes 0 to 100, and the default of -1 means about 75. 85 keeps photos looking clean without a large file; go lower for thumbnails.

How do I check that GD supports WebP?

Run php -r "var_dump(gd_info()['WebP Support'] ?? false);" and look for bool(true). If it prints false, your PHP build's GD was compiled without WebP.