Auto-Convert Image to WebP in WordPress (Programmatically)

Hey there, fellow WordPress wrangler! 👋

Ever felt like your site’s loading slower? Yeah, me too. If you’re looking for ways to optimize your WordPress site without compromising on quality. One of the easiest ways to do that is by converting your images to the WebP format, which is a more efficient image format that can reduce file size without sacrificing quality. The best part? You can automate this process directly within WordPress!

In this blog post, I’ll show you how to use a simple PHP script to automatically convert images to WebP format when uploading to the WordPress media library. Plus, I’ll guide you through different methods to integrate this script into your WordPress site. Let’s dive in!

Why Convert Images to WebP?

First things first – what the heck is WebP? Before we jump into the code, let’s quickly talk about why WebP is a big deal.

WebP is a modern image format developed by Google, offering superior lossless and lossy compression for images on the web. According to Google, WebP images are 25-34% smaller in size compared to JPEGs and PNGs. Smaller images mean faster load times, which translates to better SEO, a smoother user experience, and less bandwidth usage. All good things, right?

The PHP Script for Automatic WebP Conversion

Alright, buckle up. Here’s the star of the show: a simple PHP script that automatically converts JPEG and PNG images to WebP format during upload.

<?php

// Original code with inline comments and suggestions
function nin_convert_to_webp_upload($file) {
    // Checking if the file is an image
    if (strpos($file['type'], 'image') !== false) {
        $image_path = $file['tmp_name'];
        $webp_path = $image_path . '.webp';
        
        // Checking file extension
        $file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $allowed_extensions = ['jpg', 'jpeg', 'png'];

        if (in_array(strtolower($file_extension), $allowed_extensions)) {
            // Checking for GD library
            if (function_exists('imagewebp')) {
                // Use switch statement for different image types
                switch (strtolower($file_extension)) {
                    case 'jpg':
                    case 'jpeg':
                        $image = imagecreatefromjpeg($image_path);
                        break;
                    case 'png':
                        $image = imagecreatefrompng($image_path);
                        // Preserve transparency for PNG
                        imagealphablending($image, false);
                        imagesavealpha($image, true);
                        break;
                    default:
                        return $file; // Unsupported image type
                }

                // Set WebP quality
                $webp_quality = 80; // Adjust as needed

                if ($image !== false) {
                    // Add error handling and logging
                    if (imagewebp($image, $webp_path, $webp_quality)) {
                        imagedestroy($image);
                        
                        // Replace original with WebP
                        unlink($image_path);
                        rename($webp_path, $image_path);

                        // Update file information
                        $file['name'] = preg_replace('/\.(jpe?g|png)$/i', '.webp', $file['name']);
                        $file['type'] = 'image/webp';
                    } else {
                        // Log the error
                        error_log("Failed to convert {$file['name']} to WebP");
                    }
                } else {
                    // Log the error
                    error_log("Failed to create image resource for {$file['name']}");
                }
            } else {
                // Log the missing GD library
                error_log("GD library with WebP support is not available");
            }
        }
    }

    return $file;
}

add_filter('wp_handle_upload_prefilter', 'nin_convert_to_webp_upload');

// Add WebP support check for the server
function nin_check_webp_support() {
    if (!function_exists('imagewebp')) {
        add_action('admin_notices', function() {
            echo '<div class="error"><p>WebP conversion is not available. Please enable GD library with WebP support.</p></div>';
        });
    }
}
add_action('admin_init', 'nin_check_webp_support');
PHP
Expand

How This Script Works

This PHP script hooks into the WordPress upload process using the wp_handle_upload_prefilter filter. Here’s a quick rundown of what the script does:

  1. Checks for WebP Support on the Server: A new function, check_webp_support(), checks if your server supports WebP conversion and notifies you in the WordPress admin if it doesn’t.
  2. Checks if the uploaded file is an image: The script first checks if the uploaded file is an image by inspecting its MIME type.
  3. Verifies the file extension: It then checks if the image is in JPEG, JPG, or PNG format, as these are the formats we want to convert to WebP.
  4. Converts the image to WebP: The script uses a switch statement to handle different image types, ensuring the correct function is used to create an image resource. For PNG images, it even preserves transparency.
  5. Sets WebP Quality: The script allows you to adjust the WebP quality with the $webp_quality variable, giving you control over the balance between file size and image quality.
  6. Handles Errors Gracefully: The script includes error handling and logs any issues that occur during the conversion process, helping you troubleshoot if something goes wrong.
  7. Replaces the original image: If the conversion is successful, the script replaces the original image file with the newly created WebP version and updates the file information accordingly.

Adding the Script to Your WordPress Site

Now, how do we get this script into WordPress? There are a few different ways you can do this, depending on your preference and technical comfort level. Choose your weapon:

1. The “I am a Proper Dev” Method: Create a Custom Plugin

If you want a more portable solution, creating a custom plugin is the way to go. This method keeps your code separate from your theme, so you won’t lose it if you change themes.

  1. Create a new folder in the wp-content/plugins directory. Call it something cool like webp-ninja.
  2. Inside that folder, create a new webp-ninja.php PHP file.
  3. Paste the script into this file:
<?php
/*
Plugin Name: WebP Ninja
Plugin URI: https://singhnitin.com/auto-convert-image-to-webp-in-wordpress-programmatically
Description: Automatically converts JPEG and PNG images to WebP format during upload.
Version: 1.0
Author: Nitin Singh
Author URI: https://singhnitin.com
Text Domain: webp-ninja
*/

// Original code with inline comments and suggestions
function webp_ninja_convert_to_webp_upload($file) {
    // Checking if the file is an image
    if (strpos($file['type'], 'image') !== false) {
        $image_path = $file['tmp_name'];
        $webp_path = $image_path . '.webp';
        
        // Checking file extension
        $file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $allowed_extensions = ['jpg', 'jpeg', 'png'];

        if (in_array(strtolower($file_extension), $allowed_extensions)) {
            // Checking for GD library
            if (function_exists('imagewebp')) {
                // Use switch statement for different image types
                switch (strtolower($file_extension)) {
                    case 'jpg':
                    case 'jpeg':
                        $image = imagecreatefromjpeg($image_path);
                        break;
                    case 'png':
                        $image = imagecreatefrompng($image_path);
                        // Preserve transparency for PNG
                        imagealphablending($image, false);
                        imagesavealpha($image, true);
                        break;
                    default:
                        return $file; // Unsupported image type
                }

                // Set WebP quality
                $webp_quality = 80; // Adjust as needed

                if ($image !== false) {
                    // Add error handling and logging
                    if (imagewebp($image, $webp_path, $webp_quality)) {
                        imagedestroy($image);
                        
                        // Replace original with WebP
                        unlink($image_path);
                        rename($webp_path, $image_path);

                        // Update file information
                        $file['name'] = preg_replace('/\.(jpe?g|png)$/i', '.webp', $file['name']);
                        $file['type'] = 'image/webp';
                    } else {
                        // Log the error
                        error_log("Failed to convert {$file['name']} to WebP");
                    }
                } else {
                    // Log the error
                    error_log("Failed to create image resource for {$file['name']}");
                }
            } else {
                // Log the missing GD library
                error_log("GD library with WebP support is not available");
            }
        }
    }

    return $file;
}

add_filter('wp_handle_upload_prefilter', 'webp_ninja_convert_to_webp_upload');

// Add WebP support check for the server
function webp_ninja_check_webp_support() {
    if (!function_exists('imagewebp')) {
        add_action('admin_notices', function() {
            echo '<div class="error"><p>WebP conversion is not available. Please enable GD library with WebP support.</p></div>';
        });
    }
}
add_action('admin_init', 'webp_ninja_check_webp_support');
PHP
  1. Save the file and activate your plugin from the WordPress dashboard.

2. The “I Live Dangerously” Method: Add to Your Theme’s functions.php File

This is probably the most straightforward method. Simply open your theme’s functions.php file and paste the script at the bottom.

  1. Find and open your child theme’s functions.php.
  2. Scroll to the bottom of the file and paste the PHP script.
  3. Save the functions.php file.

3. The “I am Lazy But Smart” Method: Use a Code Snippets Plugin

If you’re not comfortable editing theme files or creating custom plugins, a code snippets plugin can be a great alternative. These plugins allow you to add custom code to your site without touching any files.

  • Install and activate a code snippets plugin like Code Snippets.
  • Create a new snippet and paste the PHP script into the code editor.
  • Save and activate the snippet.

Final Thoughts

Optimizing your WordPress site’s performance is a continuous process, and converting images to WebP is a powerful way to make an immediate impact. With the script provided in this post, you can automate the conversion process and ensure that your images are always served in the most efficient format possible.

Whether you decide to add the script to your theme’s functions.php file, create a custom plugin, or use a code snippets plugin, the choice is yours. Just pick the method that fits best with your workflow and technical skill level.

And remember, always test your site thoroughly after making any changes, especially when working with image files. You don’t want to accidentally break something that was working perfectly before.

Happy coding! If you have any questions or run into any issues, feel free to drop a comment below. I’m always here to help fellow WordPress developers.

Leave a Reply