Luc Shelton

SilverStripe Module: Automatic WebP Image Conversion SilverStripe Module: Automatic WebP Image Conversion

SilverStripe Module: Automatic WebP Image Conversion

SilverStripe Module: Automatic WebP Image Conversion

This is a SilverStripe module for automatically converting any image assets that are scaled, resized, or rasterized through SilverStripe's backend system for altering and rendering images. You can read more about the templating syntax for manipulating images here.

This module provides a custom implementation for the FlysystemAssetStore type, which intercepts invocations of functions responsible for retrieving the file names for cached and resized images. Each time this function is called, a check is made to determine whether there is a .webp counterpart of the image being requested. If none is available then it will automatically attempt to create the .webp version of the image by using some of the available LibGD functions, including imagewebp.

The image conversion to WebP is done in this snippet of code from the module.

<?php

...

public function createWebPImage($path, $filename, $hash, $variant = false)
{

    if (!function_exists('imagewebp') || !function_exists('imagecreatefromjpeg') || !function_exists('imagecreatefrompng')) {
        return;
    }

    $orgpath = './' . $this->getAsURL($filename, $hash, $variant);
    $webpImageRelativeFilePath = $this->createWebPName($orgpath);
    list($width, $height, $type, $attr) = getimagesize($path);

    switch ($type) {
        case IMAGETYPE_GIF:
            $img = imagecreatefromgif($path);
            imagepalettetotruecolor($img);
            imagesavealpha($img, true); // save alphablending setting (important)
            // imagewebp($img, $webpImageRelativeFilePath, $this->webp_quality);
            break;
        case IMAGETYPE_JPEG:
            $img = imagecreatefromjpeg($path);
            // imagewebp($img, $webpImageRelativeFilePath, $this->webp_quality);
            break;
        case IMAGETYPE_PNG:
            $img = imagecreatefrompng($path);
            imagesavealpha($img, true); // save alphablending setting (important)
            break;
    }

    if ($img) {
        imagewebp($img, $webpImageRelativeFilePath, $this->webp_quality);
        imagedestroy($img);
    }
}

...

The custom LoveDuckieFlysystemAssetStore type is injected into the framework through the Injector type. This is what enables the type to intercept invocations to member functions of the FlysystemAssetStore.

This module additionally requires that you use an NGINX server configuration similar to the one found in the snippet below.

map $http_accept $webp_suffix {
  default   "";
  "~*webp"  ".webp";
}

location ~* /assets/.+\.(?<extension>jpe?g|png|gif|webp)$ {
    # more_set_headers 'Content-Type: image/webp';
    gzip_static on;
    gzip_types image/png image/x-icon image/webp image/svg+xml image/jpeg image/gif;

    add_header Vary Accept;
    expires max;
    sendfile on;
    try_files "${request_uri}${webp_suffix}" $uri =404;
}

The NGINX server will attempt to server .webp counterparts of image assets if they are discoverable from the same server.

Relevant Links