11

Case: I have a client that doesn't know much about the digital world. However what she does know is how to get the photo's from her camera on to the computer and in WordPress. However she doesn't know how to downsize the photo's to a normal size.

Solution: I like WordPress to automatically downsize those photo's in the background to a maximum width of 1024px.

Problem: Although I can set maximum width in the settings, I can set the $content_width and I can add new image sizes with 'add_image_size'. The original photo is still stored in the upload-folder in it's original size. Meaning the harddisk space will easily get full.

Question: What should I put in functions.php to let WordPress downsize the original image (if it's larger then the maximum width)?

2 Answers 2

6

I was able to solve it using the following code:

function my_handle_upload ( $params )
{
    $filePath = $params['file'];

    if ( (!is_wp_error($params)) && file_exists($filePath) && in_array($params['type'], array('image/png','image/gif','image/jpeg')))
    {
        $quality                        = 90;
        list($largeWidth, $largeHeight) = array( get_option( 'large_size_w' ), get_option( 'large_size_h' ) );
        list($oldWidth, $oldHeight)     = getimagesize( $filePath );
        list($newWidth, $newHeight)     = wp_constrain_dimensions( $oldWidth, $oldHeight, $largeWidth, $largeHeight );

        $resizeImageResult = image_resize( $filePath, $newWidth, $newHeight, false, null, null, $quality);

        unlink( $filePath );

        if ( !is_wp_error( $resizeImageResult ) )
        {
            $newFilePath = $resizeImageResult;
            rename( $newFilePath, $filePath );
        }
        else
        {
            $params = wp_handle_upload_error
            (
                $filePath,
                $resizeImageResult->get_error_message() 
            );
        }
    }

    return $params;
}
add_filter( 'wp_handle_upload', 'my_handle_upload' );

The original file was 3,3Mb after it was uploaded, with large dimensions set to 2048x2048, it took only 375Kb on the server (about 90% reduction!)

3
  • 1
    Would you mind if I used this in a blogpost alongside the other code in my answer?
    – Tom J Nowell
    Commented Dec 19, 2012 at 17:18
  • If you find it useful, I don't mind, what's your blog?
    – Mark
    Commented Dec 20, 2012 at 10:52
  • My site's tomjn.com, I've not written the post yet, I'll do so over the next week and post the URL here when I'm done
    – Tom J Nowell
    Commented Dec 20, 2012 at 12:01
3

Resizing is already done to create the large/medium/thumb sizes, but the problem your facing is that the image is too large to resize, either because of a lack of memory or time.

So resizing isn't an option, if it weren't you wouldn't have your issue. Instead, try limiting the images, so if a 20MB upload happens, it's denied with a message indicating that it needs to be downsized.

Limiting based on image area/megapixels:

<?php
/**
 * Plugin Name: Deny Giant Image Uploads
 * Description: Prevents Uploads of images greater than 3.2MP
 */

function tomjn_deny_giant_images($file){
    $type = explode('/',$file['type']);

    if($type[0] == 'image'){
        list( $width, $height, $imagetype, $hwstring, $mime, $rgb_r_cmyk, $bit ) = getimagesize( $file['tmp_name'] );
        if($width * $height > 3200728){ // I added 100,000 as sometimes there are more rows/columns than visible pixels depending on the format
            $file['error'] = 'This image is too large, resize it prior to uploading, ideally below 3.2MP or 2048x1536';
        }
    }
    return $file;
}
add_filter('wp_handle_upload_prefilter','tomjn_deny_giant_images');

Limiting based on width or height:

https://wordpress.stackexchange.com/posts/67110/revisions

<?php
/** Plugin Name: (#67107) »kaiser« Restrict file upload */

function wpse67107_restrict_upload( $file )
{
    $file_data = getimagesize( $file );
    // Handle cases where we can't get any info:
    if ( ! $file_data )
        return $file;

    list( $width, $height, $type, $hwstring, $mime, $rgb_r_cmyk, $bit ) = $file_data;

    // Add conditions when to abort
    if ( $width > 2048 )
        $file['error'] = 'Error statement';

    return $file;
}
add_filter( 'wp_handle_upload_prefilter', 'wpse67107_restrict_upload' );

Limiting by area would allow tall/thin or wide/short images that can be resized, limiting by dimensions may be easier to explain

5
  • Well I have been thinking hard in what I want and what I want is that the original image will get the same size as the dimension set to the 'Large' image size. In order to do that I think I have to check with 'wp_handle_upload' what do you think?
    – Mark
    Commented Dec 19, 2012 at 14:51
  • Ah so you do have the large/medium sizes, you just want to prevent the original from being used? I thought you meant she was uploading massive images and the massive version was always being used and it wasnt generating the smaller versions?
    – Tom J Nowell
    Commented Dec 19, 2012 at 15:01
  • 1
    But that hook sounds about the right place, or even the wp_handle_upload_prefilter filter used in the ones I listed above, some PHP resizing code rather than the addition of an error could do the trick so long as you write back to the original file. Testing will be needed though
    – Tom J Nowell
    Commented Dec 19, 2012 at 15:03
  • You are correct. All proper sizes are being generated I just don't understand why WordPress would keep the original when the dimensions has been set in the Settings page. Or maybe make a check-in option with "Keep Original" which you can opt-out. Just my 2 cents...
    – Mark
    Commented Dec 19, 2012 at 15:08
  • 1
    because it needs to save the file in order to then use it for the other sizes, and it's needed if any modifications are done or regeneration
    – Tom J Nowell
    Commented Dec 19, 2012 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.