Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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)?

share|improve this question

2 Answers 2

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!)

share|improve this answer
1  
Would you mind if I used this in a blogpost alongside the other code in my answer? –  Tom J Nowell Dec 19 '12 at 17:18
    
If you find it useful, I don't mind, what's your blog? –  Mark Dec 20 '12 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 Dec 20 '12 at 12:01

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:

http://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

share|improve this answer
    
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 Dec 19 '12 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 Dec 19 '12 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 Dec 19 '12 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 Dec 19 '12 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 Dec 19 '12 at 16:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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