Blog, WordPress, WordPress Snippet Codes

WebP Image Format

What is WebP image format?

WebP is a next-gen image format employing both lossy and lossless compression. It is true-color graphics on the web, producing smaller files of comparable image quality to the older JPEG scheme.

Supported Browsers

Google Chrome, Firefox, Opera, GNOME Web, Midori, and Falkon natively support.

EdgeHTML based versions of Microsoft Edge support through a platform extension (installed by default), but not when running in the Application Guard mode. Since versions of Microsoft Edge released after January 2020 are based on the Chromium browser, WebP support is built-in without the need of platform extensions.

Safari added support for WebP with iOS 14 and upcoming macOS Big Sur.

It can also be displayed in all major browsers using the WebPJS JavaScript library, although support in Internet Explorer 6 and above is achieved using Flash.

Supported Android

Lossy WebP images are supported in Android 4.0 (API level 14) and higher, and lossless and transparent WebP images are supported in Android 4.3 (API level 18) and higher.

Using in HTML

Using this format in HTML is like using any other kind of image.

<img src="img/myimage.webp" alt="WebP Image" />

Some browsers don’t support this format. To solve this issue, use <picture> tag to display images.

<picture>
  <source srcset="img/myimage.webp" type="image/webp">
  <source srcset="img/myimage.jpg" type="image/jpeg"> 
  <img src="img/myimage.jpg" alt="Not WebP Image">
</picture>

This is probably your best best for the broadest possible compatibility because it will work in every single browser, not just those that support the <picture> element.

Using in CSS

Unlike the element in HTML which falls back gracefully to the <img> element in all browsers, CSS doesn’t provide a built-in solution for fallback images that’s optimal.

Modernizr is a well-known feature detection library that detects available features in browsers. When you add this custom build to your website via the <script> tag, it will automatically add one of two classes to the <html> element:

  • The “webp” class is added when the browser supports.
  • The “no-webp” class is added when the browser doesn’t support it.

With these classes, you’ll be able to use CSS to load background images according to a browser’s capability by targeting the class on the tag:

.no-webp .elementWithBackgroundImage {
  background-image: url("myimage.jpg");
}

.webp .elementWithBackgroundImage{
  background-image: url("myimage.webp");
}

Using when JavaScript is disabled

If you’re depending on Modernizr, you have to think about those users who have JavaScript disabled.

To get around this, we’ll start by adding a class of no-js to the <html> tag:

<html class="no-js">

We’ll then write a small piece of inline script that we’ll place before any other scripts:

<script>
  document.documentElement.classList.remove("no-js");
</script>

This will remove the no-js class on the <html> element when parsed.

When JavaScript is disabled, this small script never runs, so the no-js class will stay on the element. This means we can add another rule to provide an image type that has the widest support:

.no-js .elementWithBackgroundImage {
  background-image: url("myimage.jpg");
}

This covers all our bases. If JavaScript is available, the inline script is run and removes the no-js class before the CSS is parsed, so the JPEG is never downloaded in a WebP-capable browser. If JavaScript is indeed turned off, then the class is not removed and the more compatible image format is used.

Converting Images to WebP with Node.js

To converting images with Node.js you need Node installed before. If not, install it.

After installation, go to your project root in the terminal window and install “imagemin” and the “imagemin-webp” on the project with Node Package Manager.

npm install imagemin imagemin-webp

Now open your text editor and name it “mywebp.js”.

Type the script below into the file:

var imagemin = require("imagemin"),    // The imagemin module.
  webp = require("imagemin-webp"),   // imagemin's WebP plugin.
  outputFolder = "./img",            // Output folder
  PNGImages = "./img/*.png",         // PNG images
  JPEGImages = "./img/*.jpg";        // JPEG images

imagemin([PNGImages], outputFolder, {
  plugins: [webp({
      lossless: true // Losslessly encode images
  })]
});

imagemin([JPEGImages], outputFolder, {
  plugins: [webp({
    quality: 65 // Quality setting from 0 to 100
  })]
});

This script will process all JPEG and PNG images in the “img” folder and convert them to WebP.

This script assumes that all of your JPEG and PNG images are in a folder named “img”. Once you’re ready, run the script like so:

node mywebp.js

Converting Images with PHP

Using with function below you can convert jpeg, jpg, png and gif format.

function hs_webp_image($file, $compression_quality = 80){
    // check if file exists
    if (!file_exists($file)) {
        return false;
    }

    // If output file already exists return path
    $output_file = basename($file,'.'. pathinfo($file,PATHINFO_EXTENSION)) . '.webp';
    if (file_exists($output_file)) {
        return $output_file;
    }

    $file_type = strtolower(pathinfo($file, PATHINFO_EXTENSION));

    if (function_exists('imagewebp')) {

        switch ($file_type) {
            case 'jpeg':
            case 'jpg':
                $image = imagecreatefromjpeg($file);
                break;

            case 'png':
                $image = imagecreatefrompng($file);
                imagepalettetotruecolor($image);
                imagealphablending($image, true);
                imagesavealpha($image, true);
                break;

            case 'gif':
                $image = imagecreatefromgif($file);
                break;
            default:
                return false;
        }

        // Save the image
        $result = imagewebp($image, $output_file, $compression_quality);
        if (false === $result) {
            return false;
        }

        // Free up memory
        imagedestroy($image);

        return $output_file;
    } elseif (class_exists('Imagick')) {
        $image = new Imagick();
        $image->readImage($file);

        if ($file_type === 'png') {
            $image->setImageFormat('webp');
            $image->setImageCompressionQuality($compression_quality);
            $image->setOption('webp:lossless', 'true');
        }

        $image->writeImage($output_file);
        return $output_file;
    }

    return false;
}

Support WebP in WordPress

WordPress by default does not support WebP image format. To force WordPress to upload this format, you need to add the function below to the functions.php file.

if (!function_exists('hs_webp_upload_mimes')) {
     function hs_webp_upload_mimes($existing_mimes)
     {
          $existing_mimes['webp'] = 'image/webp';
          return $existing_mimes;
     }
     add_filter('mime_types', 'hs_webp_upload_mimes');
}

To display the WebP image format in the Media section, we must add the function below in functions.php.

if (!function_exists('hs_webp_is_displayable')) {
     function hs_webp_is_displayable($result, $path)
     {
          if ($result === false) {
               $displayable_image_types = array(IMAGETYPE_WEBP);
               $info = @getimagesize($path);
               if (empty($info)) {
                    $result = false;
               } elseif (!in_array($info[2], $displayable_image_types)) {
                    $result = false;
               } else {
                    $result = true;
               }
          }
          return $result;
     }
     add_filter('file_is_displayable_image', 'hs_webp_is_displayable', 10, 2);
}

Now you can upload WebP images and see them in Media section.

References:

Using WebP Images

Upload WebP Image Format on WordPress

Convert images to WebP using PHP