PHP Webp image generator and HTML code

One way to increase your website speed is to use images smaller in size, even small amounts of data can make huge diference for mobile users on slower connection.

Google page-speed documents recommends switching to webp image format, this is basically another file format, just like .png or .jpg, the .webp images are usually 4-5 times smaller in size with minimal or no quality differences.

We will create a script that will automatically generate .webp images from existent .jpg/png/gif files on site, and we will show you best way to display these images.

1) Install server programs that convert images to .webp

On your server you can convert images to webp with cwebp and gif2webp

You can install them with yum:

yum install libwebp.x86_64
yum install libwebp-tools.x86_64

2) Create an empty folder named "webp" inside your site root

3) Add these new lines to your .htaccess file

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^webp/(.*)\.webp?$ webp_generator.php?file=$1 [QSA]

The htaccess code will first check if the webp image file was already generated, if it is, then it will display it automatically, bypassing the script.

4) Create a file that generates webp images automatically inside /webp folder

Create a file named webp_generator.php and place it in your site root, paste the next code in it.

If now you have an image /images/landscape.jpg, you will be able to access a webp file named /webp/images/landscape.jpg.webp

The code is kind of fast, a generated image will be loaded directly bypassing the script next time

The script is made to clear images from /webp every 30 days (see commented code), so do NOT store permanent images there that you might need. Treat the /webp folder as a temporary cache folder

<?php
// get an absolute path
$settings_document_root = dirname(__FILE__);
$file = trim(strip_tags($_GET['file']));
// exit if ORIGINAL file not found
if(!is_file($file)){
  
  // include("404.php");
  echo "original file not found";
  exit;
}
// detect if file is png/jpg/gif, for gif we use gif2webp command
$file_extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
// mkdir -p to create parent directories if needed (e.g a full path of sub directories)
exec("mkdir -p ".escapeshellarg("webp/".dirname($file)));

// convert png, jpg
if($file_extension=="png" or $file_extension=="jpg"){
  exec("cwebp -q 80 ".escapeshellarg($settings_document_root."/".$file)." -o ".escapeshellarg($settings_document_root."/webp/".$file.".webp"));
}
// convert gif
if($file_extension=="gif"){
  exec("gif2webp -q 80 ".escapeshellarg($settings_document_root."/".$file)." -o ".escapeshellarg($settings_document_root."/webp/".$file.".webp"));
}

// show warning if file was not generated properly, you can replace this with a header() redirect to a default image
if(!file_exists($settings_document_root."/webp/".$file.".webp")){
  echo "cannot generate webp file ".escapeshellarg("webp/".$file);
  exit;
}

// maintenance, delete old webp files, then delete empty directories
exec("find webp/ -type f -mtime +30 -delete");
exec("find webp/ -type d -empty -delete");

// continue to showing the generated web file
// the ?time() is there so that it doesn't redirect back to itself on first time when image is generated
// that can cause an infinite loop because it caches file as a redirect back to itself
header("Location: /webp/".$file.".webp?".time());
exit;
?>

5) change your html code to display .webp images

Not all browsers support webp images, but this sample code will fallback to a jpg or another image if user browser doesn't understand .webp images.

A normal image like <img src="/images/landscape.jpg"> can be displayed in webp format by the next code.

Notice the path starting with /webp and ending with .webp , that is our above script generating the webp images automatically

<picture>
<source srcset="/webp/images/landscape.jpg.webp" type="image/webp">
<img src="/images/landscape.jpg">
</picture>