WordPress Upload to WebP Converter

Automatically converts uploaded images to WebP format with resizing and quality optimization for faster WordPress sites

<?php
 
/**
 * Microbite WebP Converter 
 * 
 * Automatically converts uploaded images (JPEG, PNG, GIF, HEIC) to optimized WebP format.
 * This snippet is perfect for handling large image uploads - it intelligently resizes images
 * to your specified dimensions and converts them to WebP for maximum compression while
 * maintaining quality. Original files are replaced with optimized versions to save server space.
 * 
 * Features:
 * - Automatic WebP conversion with size comparison (only converts if WebP is smaller)
 * - Configurable max width/height with aspect ratio preservation  
 * - Adjustable compression quality (1-100)
 * - EXIF orientation correction (fixes rotated images)
 * - Replaces originals with optimized files (saves storage space)
 * - Admin settings panel in Media options
 * - Smart fallback (keeps original if WebP conversion fails or is larger)
 * 
 * Requirements: 
 * - WordPress 5.0+
 * - PHP Imagick extension (will show admin notice if missing)
 * 
 * Installation Options:
 * 1. Add to your theme's functions.php file
 * 2. Save as a must-use plugin (wp-content/mu-plugins/webp-converter.php)
 * 3. Use with code snippet plugins (WPCode, Code Snippets, Fluent Snippets, etc.)
 * 4. Add to your child theme's functions.php for theme updates safety
 * 
 * For a more professional solution with advanced features and support,
 * check out Microbite Image Converter: https://www.imageconverter.com.au/
 *
 * @version 1.03
 * @author Microbite (info@microbite.com.au)
 */

function mbwpc_admin_enqueue_styles() {
    wp_enqueue_style('mbwpc-admin-styles', plugin_dir_url(__FILE__) . 'css/mbwpc-styles.css', array(), '1.0.0', 'all');
}
add_action('admin_enqueue_scripts', 'mbwpc_admin_enqueue_styles');

add_action('init', 'mbwpc_plugin_init');

function mbwpc_plugin_init() {
    add_action('admin_notices', 'mbwpc_admin_notices');
    add_action('admin_init', 'mbwpc_register_settings');
    add_filter('wp_handle_upload', 'mbwpc_handle_upload_convert_to_webp');
}

/**
 * Display admin notices for Imagick extension and WebP conversion settings.
 */
function mbwpc_admin_notices() {
    $screen = get_current_screen();
    if ('upload' === $screen->id || 'media' === $screen->id) {
        if (!extension_loaded('imagick')) {
            echo "<div class='notice notice-warning is-dismissible'><p><strong>Warning:</strong> The Imagick PHP extension required for WebP conversion is not installed or enabled. Please install or enable Imagick.</p></div>";
        } else {
            $settings_url = admin_url('options-media.php');
            $webp_conversion_enabled = get_option('mbwpc_convert_to_webp', false);

            if ($webp_conversion_enabled) {
                echo "<div class='notice notice-info is-dismissible'><p><strong>Enabled:</strong> WebP image conversion is active. You can disable this feature on the <a href='" . esc_url($settings_url) . "'>Settings > Media</a> page.</p></div>";
            } else {
                echo "<div class='notice notice-info is-dismissible'><p><strong>Disabled:</strong> WebP image conversion is not active. You can enable this feature on the <a href='" . esc_url($settings_url) . "'>Settings > Media</a> page.</p></div>";
            }
        }
    }
}

/**
 * Register settings for WebP conversion and image processing.
 */
function mbwpc_register_settings() {
    register_setting('media', 'mbwpc_convert_to_webp', [
        'type' => 'boolean',
        'sanitize_callback' => 'rest_sanitize_boolean',
        'default' => false,
    ]);

    register_setting('media', 'mbwpc_max_width', [
        'type' => 'integer',
        'sanitize_callback' => 'absint',
        'default' => 1920,
    ]);

    register_setting('media', 'mbwpc_max_height', [
        'type' => 'integer',
        'sanitize_callback' => 'absint',
        'default' => 1080,
    ]);

    register_setting('media', 'mbwpc_compression_quality', [
        'type' => 'integer',
        'sanitize_callback' => function($value) {
            return max(1, min(100, absint($value)));
        },
        'default' => 80,
    ]);

    add_settings_field(
        'mbwpc_convert_to_webp',
        __('Convert Uploaded Images to WebP', 'mbwpc'),
        'mbwpc_field_callback',
        'media',
        'default',
        ['label_for' => 'mbwpc_convert_to_webp']
    );

    add_settings_field(
        'mbwpc_image_settings',
        __('Image Processing Settings', 'mbwpc'),
        'mbwpc_image_settings_callback',
        'media',
        'default'
    );
}

/**
 * Display the image processing settings fields.
 */
function mbwpc_image_settings_callback() {
    $maxWidth = get_option('mbwpc_max_width', 1920);
    $maxHeight = get_option('mbwpc_max_height', 1080);
    $compressionQuality = get_option('mbwpc_compression_quality', 80);

    echo '<fieldset>';
    echo '<p><label for="mbwpc_max_width">Max Width (pixels):</label><br>';
    echo '<input type="number" id="mbwpc_max_width" name="mbwpc_max_width" value="' . esc_attr($maxWidth) . '" min="1" max="9999" /></p>';
    
    echo '<p><label for="mbwpc_max_height">Max Height (pixels):</label><br>';
    echo '<input type="number" id="mbwpc_max_height" name="mbwpc_max_height" value="' . esc_attr($maxHeight) . '" min="1" max="9999" /></p>';
    
    echo '<p><label for="mbwpc_compression_quality">Compression Quality (1-100):</label><br>';
    echo '<input type="number" id="mbwpc_compression_quality" name="mbwpc_compression_quality" value="' . esc_attr($compressionQuality) . '" min="1" max="100" /></p>';
    echo '</fieldset>';
}

/**
 * Display the WebP conversion setting field.
 */
function mbwpc_field_callback() {
    $value = get_option('mbwpc_convert_to_webp', false);
    echo '<input type="checkbox" id="mbwpc_convert_to_webp" name="mbwpc_convert_to_webp" ' . checked(1, $value, false) . ' value="1">';
    echo '<label for="mbwpc_convert_to_webp">' . esc_html__('Enable automatic conversion of uploaded images to WebP format.', 'mbwpc') . '</label>';
}

/**
 * Handle the image upload and convert to WebP format.
 *
 * @param array $upload Array containing the upload data.
 * @return array Modified upload data.
 */
function mbwpc_handle_upload_convert_to_webp($upload) {
    if (!get_option('mbwpc_convert_to_webp')) {
        return $upload; // Skip the conversion if not enabled
    }

    $maxWidth = get_option('mbwpc_max_width', 1920);
    $maxHeight = get_option('mbwpc_max_height', 1080);
    $compressionQuality = get_option('mbwpc_compression_quality', 80);

    $valid_types = ['image/jpeg', 'image/png', 'image/gif', 'image/heic'];

    if (in_array($upload['type'], $valid_types)) {
        $file_path = $upload['file'];

        if (extension_loaded('imagick')) {
            try {
                $imagick = new Imagick($file_path);

                // Adjust orientation based on EXIF data
                switch ($imagick->getImageOrientation()) {
                    case Imagick::ORIENTATION_BOTTOMRIGHT:
                        $imagick->rotateImage("#000", 180);
                        break;
                    case Imagick::ORIENTATION_RIGHTTOP:
                        $imagick->rotateImage("#000", 90);
                        break;
                    case Imagick::ORIENTATION_LEFTBOTTOM:
                        $imagick->rotateImage("#000", -90);
                        break;
                }

                $imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);

                $originalWidth = $imagick->getImageWidth();
                $originalHeight = $imagick->getImageHeight();
                $aspectRatio = $originalWidth / $originalHeight;
                $newWidth = $originalWidth;
                $newHeight = $originalHeight;

                if ($originalWidth > $maxWidth || $originalHeight > $maxHeight) {
                    if ($newWidth > $maxWidth) {
                        $newWidth = $maxWidth;
                        $newHeight = $newWidth / $aspectRatio;
                    }
                    if ($newHeight > $maxHeight) {
                        $newHeight = $maxHeight;
                        $newWidth = $newHeight * $aspectRatio;
                    }
                }

                $imagick->resizeImage($newWidth, $newHeight, Imagick::FILTER_LANCZOS, 1);
                $imagick->setImageFormat('webp');
                $imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
                $imagick->setImageCompressionQuality($compressionQuality);

                $file_info = pathinfo($file_path);
                $dirname = $file_info['dirname'];
                $filename = $file_info['filename'];
                $new_file_path = $dirname . '/' . $filename . '.webp';
                $imagick->writeImage($new_file_path);

                // Compare file sizes
                $original_size = filesize($file_path);
                $new_size = filesize($new_file_path);

                if ($new_size < $original_size) {
                    if (file_exists($new_file_path)) {
                        $upload['file'] = $new_file_path;
                        $upload['url'] = str_replace(basename($upload['url']), basename($new_file_path), $upload['url']);
                        $upload['type'] = 'image/webp';
                        @unlink($file_path);
                    }
                } else {
                    @unlink($new_file_path);
                }

                $imagick->clear();
                $imagick->destroy();

            } catch (Exception $e) {
                // Log error or handle gracefully
                error_log('WebP conversion failed: ' . $e->getMessage());
            }
        } else {
            // Only show this message to admins in debug mode
            if (defined('WP_DEBUG') && WP_DEBUG && current_user_can('manage_options')) {
                add_action('admin_notices', function() {
                    echo '<div class="notice notice-error"><p>Imagick is not installed. WebP conversion cannot be performed.</p></div>';
                });
            }
        }
    }

    return $upload;
}
?>
WordPress media settings for image sizes and formats.
  • Automatically converts uploaded images (JPEG, PNG, GIF, HEIC) to WebP format when files are uploaded to WordPress
  • Uses the Imagick PHP extension to perform the conversion
  • Only keeps the WebP version if it’s smaller than the original file
  • Image Resizing: Automatically resizes images to configurable maximum dimensions (default: 1920×1080) while maintaining aspect ratio
  • Quality Control: Allows setting compression quality (1-100, default: 80)
  • Orientation Correction: Fixes image rotation issues based on EXIF data
  • Size Optimization: Only saves the WebP version if it’s smaller than the original
WordPress media settings for image sizes and formats.

FAQs

WordPress media settings for image sizes and formats.
Review Your Cart
0
Add Coupon Code
Subtotal