-
-
Save erikyo/ebd78f0d5d1735175e5ab9ad1d4d0590 to your computer and use it in GitHub Desktop.
| <?php | |
| // README: you need GD installed | |
| function myprefix_explode_filepath( $filepath, $attachment_id ) { | |
| $uploads = wp_upload_dir(); | |
| if ( strpos( $filepath, "/" ) == false ) { | |
| return array( $uploads['basedir'], "", $filepath ); | |
| } else { | |
| list( $year, $month, $filename ) = explode( '/', $filepath ); | |
| return array( $uploads['basedir'], "$year/$month", $filename ); | |
| } | |
| } | |
| function myprefix_explode_filename( $filename ) { | |
| $filename_parts = explode( '.', $filename ); | |
| $fext = $filename_parts[ count( $filename_parts ) - 1 ]; | |
| unset( $filename_parts[ count( $filename_parts ) - 1 ] ); | |
| $fname = implode( '.', $filename_parts ); | |
| return array( $fname, $fext ); | |
| } | |
| function save_webp_copy( $metadata, $attachment_id ) { | |
| // PHP GD is required | |
| if ( ! extension_loaded( 'gd' ) ) return $metadata; | |
| // if the attachment doesn't contain resizes it isn't an image or document with previews (like pdf) | |
| if (empty($metadata['sizes'])) return $metadata; | |
| list( $basedir, $path, $filename ) = myprefix_explode_filepath( $metadata['file'], $attachment_id ); | |
| list( $fname, $fext ) = myprefix_explode_filename( $filename ); | |
| if ( isset( $metadata['mime-type'] ) ) { | |
| if ( $metadata['mime-type'] == 'pdf' ) { | |
| $file_collection = array_column( $metadata['sizes'], 'file' ); | |
| } else { | |
| return true; | |
| } | |
| } else { | |
| $file_collection = array_merge( array( $fname . "." . $fext ), array_column( $metadata['sizes'], 'file' ) ); | |
| } | |
| switch ( $fext ) { | |
| case 'jpg': | |
| foreach ( $file_collection as $value ) { | |
| $image = imagecreatefromjpeg( $basedir . '/' . $path . '/' . $value ); | |
| imagewebp( $image, $basedir . '/' . $path . '/' . $value . '.webp', 95 ); | |
| imagedestroy( $image ); | |
| } | |
| break; | |
| case 'png': | |
| foreach ( $file_collection as $value ) { | |
| $image = imagecreatefrompng( $basedir . '/' . $path . '/' . $value ); | |
| imagepalettetotruecolor( $image ); | |
| imagealphablending( $image, true ); | |
| imagesavealpha( $image, true ); | |
| imagewebp( $image, $basedir . '/' . $path . '/' . $value . '.webp', 90 ); | |
| imagedestroy( $image ); | |
| } | |
| break; | |
| default: | |
| return false; | |
| } | |
| return $metadata; | |
| } | |
| add_filter( 'wp_generate_attachment_metadata', 'save_webp_copy', 30, 2 ); | |
| function delete_webp_copy( $post_id ) { | |
| // get the file path for the image being deleted | |
| $metadata = wp_get_attachment_metadata( $post_id ); | |
| list( $basedir, $path, $filename ) = myprefix_explode_filepath( $metadata['file'], $post_id ); | |
| list( $fname, $fext ) = myprefix_explode_filename( $filename ); | |
| // create a fake metadata/size to add the main image to remove list | |
| $metadata["sizes"]["full"]["file"] = $fname . "." . $fext; | |
| // remove the webp copy from using the metadata sizes as iterator | |
| foreach ( $metadata['sizes'] as $file ) { | |
| if ( isset( $file['file'] ) && file_exists( $basedir . '/' . $path . '/' . $file['file'] . '.webp' ) ) { | |
| wp_delete_file( $basedir . '/' . $path . '/' . $file['file'] . '.webp' ); | |
| } | |
| } | |
| return $post_id; | |
| } | |
| add_filter( 'delete_attachment', 'delete_webp_copy' ); |
You have to place it inside functions.php of your WordPress template. 😉
Ok, erikyo, thanks.
Erik, this is great and nicely creates a ".webp" copy. Thank you. When you upload the image to the server, the "webp" version is created. How did you get round the "webp" version not displaying in the Media Libray? This I think needs an update to the wp_postmeta table in the database and an update to the "_wp_attached_file" entry to either add the "webp" version or overlay the jpg version. Thoughts?
Just use your webserver (nginx,apache...) to serve the file replacing the extension. take a look at this post for details:
https://modul-r.codekraft.it/2021/09/how-to-serve-automatically-webp-images-with-nginx/
Thanks Erik for the fast response. Those instructions look like they are only applicable if you're running nginx. Unfortunately running Apache. I can server webp images, that's all set up. When the new webp image is stored ideally the postmeta is updated with the correct URL, however, I appreciate this needs a little thought. The other approach would be to write a rewrite rule to request the webp impage, if all jpegs etc are converted to webp and server the jpeg should the webp not be found for some reason.
Hello, I am not sure under which folder to upload this file? Thanks