I’m finishing up an application that’s built on WordPress that has required that I programmatically resize images. When it comes to building themes or plugins, it’s relatively easy to specify add_image_size
and then let the user interface and core application do it’s thing.
But in my case, the end user will have no idea that the actual application is built on WordPress and the image resizing function needed to be a little more tailored for specific templates (or views)
So rather than use the typical WordPress facilities for uploading and resizing images, here’s how to programmatically resize images in WordPress.
The Process For Uploading Images
I’m not going to bother detailing the entire application (because there are a few helper methods that I use for doing things like validating file types and so on), but the general process is as follows:
- The user clicks on an ‘Upload Image’ element in a form that uses JavaScript to prompt them to select an image
- Once selected, the path to the file is kept in a hidden file input box
- When the user as completed the rest of the form, they submit the form during which the image is uploaded
At this point, the server-side will upload the image then also set a second, resized version of the image. For this particular project, there’s a specific-size that the image needs to be so I’m able to hardcode those values.
With that said, here’s how I’m doing it.
Programmatically Resizing Images
For the most part, uploading the image is business as usual:
- I check to see if the
$_FILES
array is set - Using a helper method, I determine if the file is a valid file type
- I upload the file
- I set the URL to the image on the post meta
Note that a ‘goal’ that you’ll see in the code is referring to a custom post type. Anyway, the code comments should be pretty clear, but here’s the code before I’m actually resizing the image:
// If the user uploaded an image, let's upload it to the server if( ! empty( $_FILES ) && isset( $_FILES['goalImage'] ) { // Store the parts of the file name into an array $file_name_parts = explode( '.', $_FILES['goalImage']['name'] ); // If the file is valid, upload the image, and store the path in the goal if( is_valid_file_type( $file_name_parts[ count( $file_name_parts ) - 1 ] ) ) { // Upload the goal image to the uploads directory, resize the image, then upload the resized version $goal_image_file = wp_upload_bits( $_FILES['goalImage']['name'], null, file_get_contents( $_FILES['goalImage']['tmp_name'] ) ); // Set post meta about this image. Need the comment ID and need the path. if( false == $goal_image_file['error'] ) { // Since we've already added the key for this, we'll just update it with the file. update_post_meta( $goal_id, 'goal_image', $goal_image_file['url'] ); } // end if/else } // end if } // end if
At this point, I’ve taken the image that the user has uploaded and placed it in the uploads
directory. No resizing has occurred.
Programmatically Resize Images
To programmatically resize images using the WordPress API, I used the image_resize
function. To resize the image, I pass it the following parameters:
- The file that the user has set to upload
- The dimensions to which I want to resize the image
- A boolean that I do not want it cropped (I want it resized)
The following code snippet shows exactly how I’m doing it:
$file_destination = image_resize( $goal_image_file['file'], 640, 480, false );
This will return a path to the file with the dimensions appended to the file name.
The challenge with this function is that the destination that it returns is essentially the fully qualified filename including the path. Of course, when uploading files, I only care about the filename itself.
To combat this, I then needed to take the returned destination, separate the various parts of the path, and just grab the filename:
// Get the actual filename (rather than the directory + filename) $filename = explode( '/', $file_destination ); $filename = $filename[ count( $filename ) - 1 ]
From here, I can then take the filename and make a second call to wp_upload_bits
and upload the resized version of the file to the uploads
directory.
$goal_image_file = wp_upload_bits( $filename, null, file_get_contents( $_FILES['goalImage']['tmp_name'] ) );
At this point, we’re back to the usual process of making sure no error occurred and then doing whatever we need to do once the upload is complete.
The Full Function
Here’s the full block of code that I’ve written to upload an image, resize it, store the resized version in the uploads
directory, and then associate the path to the file with the post meta:
// Finally, if the user uploaded an image, let's upload it to the server if( ! empty( $_FILES ) && isset( $_FILES[ 'goalImage' ] ) ) { // Store the parts of the file name into an array $file_name_parts = explode( '.', $_FILES['goalImage']['name'] ); // If the file is valid, upload the image, and store the path in the goal if( is_valid_file_type( $file_name_parts[ count( $file_name_parts ) - 1 ] ) ) { // Upload the goal image to the uploads directory, resize the image, then upload the resized version $goal_image_file = wp_upload_bits( $_FILES['goalImage']['name'], null, file_get_contents( $_FILES['goalImage']['tmp_name'] ) ); // Resize the image to fit the single goal's page dimensions $file_destination = image_resize( $goal_image_file['file'], 458, 321, false ); // Get the actual filename (rather than the directory + filename) $filename = explode( '/', $file_destination ); $filename = $filename[ count( $filename ) - 1]; // Upload the resized version of the file $goal_image_file = wp_upload_bits( $filename, null, file_get_contents( $_FILES['goalImage']['tmp_name'] ) ); // Set post meta about this image. Need the comment ID and need the path. if( false == $goal_image_file['error'] ) { // Since we've already added the key for this, we'll just update it with the file. update_post_meta( $goal_id, 'goal_image', $goal_image_file['url'] ); } // end if/else } // end if } // end if
Note that I’m not handling the case for when an error occurs – that’s beyond the scope of this post, but it’s something that should be handled in your own work.
I’ll be the first to admit that this is new territory for me. Other than that, The solution works and it appears to work well, but if any of you have suggestions for improving the actual resizing, I’m all ears.
Leave a Reply
You must be logged in to post a comment.