3

Is the world ready for the new image format WebP ?

I'm considering using it, the specs look very sexy, however, it seems like it is not supported on Firefox (and who knows which other web browsers), I noticed that a OkCupid.com is using it, but if you go there using Firefox - it seems like they are delivering JPEG instead...

I wonder how OkCupid do that - do they keep additional JPEG for each image, or maybe a HttpModule ??

I even added this on my web.config

<mimeMap fileExtension=".webp" mimeType="image/webp" />

Am I missing something? Why doesn't it work in all browsers?

Yovav
  • 2,557
  • 2
  • 32
  • 53

3 Answers3

3

After talking to James South (creator of ImageProcessor) I understand that only Chrome and Opera support WebP, in other words - the world is still not ready for WebP (try again in few years)

Yovav
  • 2,557
  • 2
  • 32
  • 53
2

The world doesn't have to be ready - you can offer two versions of your images and the browser will decide which one to take. Simply make use of the <picture> tag:

<picture>
  <source srcset="img/awesomeWebPImage.webp" type="image/webp">
  <source srcset="img/creakyOldJPEG.jpg" type="image/jpeg"> 
  <img src="img/creakyOldJPEG.jpg" alt="Alt Text!">
</picture>

If you want to use WebP inside CSS, for example for background images, you can use Modernizr that can detect if a browser supports WebP and sets a CSS class named "webp".

See also Using WebP Images for a thorough explanation.

pi3
  • 1,235
  • 13
  • 15
2

The world is now ready to webp https://caniuse.com/webp

The easier (free) way to implement it is to use rewrite, not the picture tag.

<Files *.webp>
Header set Vary "Accept-Encoding"
AddType "image/webp" .webp
AddEncoding webp .webp
</Files>
RewriteCond %{HTTP:Accept} image/webp
RewriteCond %{REQUEST_FILENAME}.webp -f
RewriteRule ^(.*)$ $1.webp [L]

EDIT : Like said in comments, of course you have to generate your webpfile with this filename : filename.jpg.webp for the file filename.jpg Here a little php function to do this (need GD or imagick):

function generateWebp($paths, $exclude, $compression_quality = 80, $method = 'gd', $replace = false) {

foreach ($paths as $path) {
    
    try {
        $Directory = new RecursiveDirectoryIterator($path);
        $Iterator = new RecursiveIteratorIterator($Directory);
        $Regex = new RegexIterator($Iterator, '/^.+(.jpe?g|.JPE?G)$/i', RecursiveRegexIterator::GET_MATCH);
        
        foreach ($Regex as $name => $Regex) {
            # Exclusions
            if (in_array($name,$exclude)) {
                continue;
            }
            
            $file = pathinfo($name);
            $output_name = $file["dirname"] . '/' . $file["filename"] . '.' . $file["extension"] . '.webp';

            # replace webp if new jpg
            if (file_exists($output_name) && ($replace || filemtime($name) > filemtime($output_name))) {
                unlink($output_name);
            }
            
            # if not exist webp, we create it
            if (!file_exists($output_name)) {
                
                if ($method === 'gd' && function_exists('imagewebp')) {
                    switch ($file['extension']) {
                        case 'jpeg':
                        case 'jpg':
                            $image = imagecreatefromjpeg($name);
                            break;
                        
                        case 'png':
                            $image = imagecreatefrompng($name);
                            imagepalettetotruecolor($image);
                            imagealphablending($image, true);
                            imagesavealpha($image, true);
                            break;
                        
                        case 'gif':
                            $image = imagecreatefromgif($name);
                            break;
                        default:
                            $image = false;
                    }
                    if(is_resource($image)){
                        imagewebp($image, $output_name, $compression_quality);
                        imagedestroy($image);
                        echo $output_name . 'généré. ';
                    }
                }
                elseif ($method === 'imagemagick' && class_exists('Imagick')) {
                    $image = new Imagick();
                    $image->readImage($name);
                    
                    if ($file_type === 'png') {
                        $image->setImageFormat('webp');
                        $image->setImageCompressionQuality($compression_quality);
                        $image->setOption('webp:lossless', 'true');
                    }
                    
                    $image->writeImage($output_name);
                    
                }
                else {
                    echo 'GD & IMAGEMAGICK non available';
                    die('NOK');
                }
            }
        }
    } catch (Exception $exception) {
        (var_dump($exception));
    }
}

}

You can also use a CDN like cloudflare with polish, not free but so conveniant

Reign.85
  • 2,420
  • 1
  • 28
  • 28
  • 1
    You forgot to mention one would need to create .webp files for every image and put them in the same folder with the exact same name but with .webp extension added. Example tom.jpg and tom.jpg.webp. I like how your answer will still work if some .webp files are missing because it checks for it in line 7. You also need to add a vary header for Accept for all image types that might be replaced with a webp image. – PHP Guru Jun 01 '22 at 00:21