Search the blog

WebP is a great image format for reducing the load times on your website. Use this PHP script below to automatically convert your images. You can run it using Cron and it will only convert images that are new or have changed.

Note that it does not convert GIFs since they could be animated and you would lose that animation during the conversion process.

function replaceImageExtension($filePath) {

    $pathInfo = pathinfo($filePath);

    if (isset($pathInfo['extension']) && in_array(strtolower($pathInfo['extension']), ['jpg', 'jpeg', 'png'])) {

        $newFilePath = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . $pathInfo['filename'] . '.webp';
        return $newFilePath;

    }

    // Return the original path if it doesn't match
    return $filePath;

}

function convertToWebP($source, $quality = 80) {

    $destination = replaceImageExtension($source);

    if (file_exists($source) === false) {

        echo "$source does not exist<br />";

        return false;

    }

    $imageInfo = getimagesize($source);
    $imageType = $imageInfo[2];

    switch ($imageType) {

        case IMAGETYPE_JPEG:

            $image = imagecreatefromjpeg($source);
            
            break;


        case IMAGETYPE_PNG:

            $image = imagecreatefrompng($source);
            
            break;


        default:

            return false;

    }

    imagepalettetotruecolor($image);
    $result = imagewebp($image, $destination, $quality);

    imagedestroy($image);

    return $result; // Return true on success, false on failure

}


function getImagesFromDirectory($folder) {

    $images = [];

    $allowedExtensions = [
        
        'jpg', 
        'png', 
        'webp'
    
    ];

    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder));

    foreach ($iterator as $fileInfo) {

        if ($fileInfo->isFile()) {

            $extension = strtolower($fileInfo->getExtension());
            $filename  = $fileInfo->getFilename();

            if (in_array($extension, $allowedExtensions) === true) {

                $images[] = $fileInfo->getPathname();

            }

        }

    }

    return $images;

}

$folders = [

    'path/to/my/images/',
    '/add/more/here/'

];

foreach ($folders as $folder) {

    // Get the images
    $images = getImagesFromDirectory($folder);

    foreach ($images as $image) {

        $ext     = pathinfo($image, PATHINFO_EXTENSION);

        // Create versions for comparison
        $jpg     = str_replace('.webp', '.jpg',  $image);
        $png     = str_replace('.webp', '.png',  $image);
        $webp    = str_replace('.jpg',  '.webp', $image);
        $webp    = str_replace('.png',  '.webp', $webp);

        // If there's a webp version but no jpg or png version, delete it
        if ($ext == 'webp' && in_array($jpg, $images) === false && in_array($png, $images) === false) {

            echo "$image deleted as it was an orphan" . PHP_EOL;
            @unlink($image);

        }

        // If there's no webp version or the jpg/png, create it
        if ($ext != 'webp' && file_exists($webp) === false) {

            echo "New webp version created of $image" . PHP_EOL;
            convertToWebP($image);

        } else if ($ext != 'webp' && file_exists($webp) === true) {

            // If the image is newer than the webp version, it's been modified so regnerate it
            $modified1 = filemtime($image);
            $modified2 = filemtime($webp);

            if ($modified1 > $modified2) {

                echo "webp version updated for $image" . PHP_EOL;
                convertToWebP($image);

            }

        }

    }

}

echo 'Done!';

This script is intended for use via the command line: php web.php;.

Tim Bennett is a Leeds-based web designer from Yorkshire. He has a First Class Honours degree in Computing from Leeds Metropolitan University and currently runs his own one-man web design company, Texelate.