Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Hook Into Wordpress Thumbnail Generation

Tags:

wordpress

I would like to do some custom processing on a certain thumbnail size in Wordpress with ImageMagick beyond the normal Wordpress functionality and am not quite sure how to go about doing this.

So I add my new thumbnail size:

add_image_size( 'new-thumb', 100, 100 );

And then this is where I'm not sure where I should hook into. Before the final copy of the thumbnail is saved within Wordpress I want to do some custom processing on it. Basic psuedo code for what I want is:

The_hook_or_action_that_fires_when_a_thumbnail_is_saved() {

    if (<Thumbnail Being Generated> == 'new-thumb') {
      $thumb_file = 'the thumbnail image we are about to save';
      $thumbfile = 'do some imagemagic stuff here';
    }

    save_thumbnail;
}

I can handle the imagemagick stuff, but I'm not sure how / where to hook this custom thumbnail processing into.

Any advise would be greatly appreciated!

like image 498
ChuckMac Avatar asked Jan 07 '13 17:01

ChuckMac


3 Answers

Thanks @brasofilo for pointing me in the right direction...

I poked around a bit and figured this one out. You can hook into wp_generate_attachment_metadata and do some image manipulation.

The basics of what I was trying to do is resize an image to a specific size ("brands" thumbnail), then expand the canvas for that thumbnail to a static height and width with a white background.

In case anyone has a similar situation I thought I would paste some code. It could be cleaned up to remove the repletion for each image type. The one issue with this code is that if the original image size is less than the desired thumbnail size it will not be generated (which is WordPress functionality).

add_image_size( 'brands', 200, 168 );

add_filter('wp_generate_attachment_metadata','replace_uploaded_image');
function replace_uploaded_image($image_data) {

    // if there is no brands image : return
    if ( !isset($image_data['sizes']['brands']) ) 
        return $image_data;

    //Set our desired static height / width (200px * 168px)
    $staticWidth  = 200;
    $staticHeight = 168;

    // paths to the uploaded image and the large image
    $upload_dir            = wp_upload_dir();
    $brands_image_location = $upload_dir['path'] . '/' . $image_data['sizes']['brands']['file'];

    // set our temp image file
    $brands_image_location_tmp = "$brands_image_location.tmp";

    // get the attributes of the source image
    list($imageWidth, $imageHeight, $imageType, $imageAttr) = getimagesize($brands_image_location);

    // there are different php functions depending on what type of image it is, so check the type
    switch($imageType) {
        //GIF
        case 1: 
            //Create a 200x168 white canvas
            $newimage=imagecreatetruecolor($staticWidth,$staticHeight);
            $white=imagecolorallocate($newimage, 255, 255, 255);
            imagefill($newimage,0,0,$white);

            //Calculate where the image should start so its centered
            if($imageWidth == $staticWidth)  { $x_pos = 0; } else { $x_pos = round( ($staticWidth - $imageWidth) / 2 ); }
            if($imageHeight == $staticHeight) { $y_pos = 0; } else { $y_pos = round( ($staticHeight - $imageHeight) / 2 ); }

            //Copy the source image to the new canvas
            $src = imagecreatefromgif($brands_image_location);
            imagecopy($newimage, $src, $x_pos, $y_pos, 0, 0, $imageWidth, $imageHeight);
            imagegif($newimage,$brands_image_location_tmp);

            // delete the uploaded image
            unlink($brands_image_location);

            // rename the temporary brands image
            rename($brands_image_location_tmp, $brands_image_location);

            // update image metadata and return them
            $image_data['sizes']['brands']['width'] = $staticWidth;
            $image_data['sizes']['brands']['height'] = $staticHeight;

            break;

        //JPG
        case 2:
            //Create a 200x168 white canvas
            $newimage=imagecreatetruecolor($staticWidth,$staticHeight);
            $white=imagecolorallocate($newimage, 255, 255, 255);
            imagefill($newimage,0,0,$white);

            //Calculate where the image should start so its centered
            if($imageWidth == $staticWidth)  { $x_pos = 0; } else { $x_pos = round( ($staticWidth - $imageWidth) / 2 ); }
            if($imageHeight == $staticHeight) { $y_pos = 0; } else { $y_pos = round( ($staticHeight - $imageHeight) / 2 ); }

            //Copy the source image to the new canvas
            $src = imagecreatefromjpeg($brands_image_location);
            imagecopy($newimage, $src, $x_pos, $y_pos, 0, 0, $imageWidth, $imageHeight);
            imagejpeg($newimage,$brands_image_location_tmp);

            // delete the uploaded image
            unlink($brands_image_location);

            // rename the temporary brands image
            rename($brands_image_location_tmp, $brands_image_location);

            // update image metadata and return them
            $image_data['sizes']['brands']['width'] = $staticWidth;
            $image_data['sizes']['brands']['height'] = $staticHeight;

            break;

        //PNG
        case 3:
            //Create a 200x168 white canvas
            $newimage=imagecreatetruecolor($staticWidth,$staticHeight);
            $white=imagecolorallocate($newimage, 255, 255, 255);
            imagefill($newimage,0,0,$white);

            //Calculate where the image should start so its centered
            if($imageWidth == $staticWidth)  { $x_pos = 0; } else { $x_pos = round( ($staticWidth - $imageWidth) / 2 ); }
            if($imageHeight == $staticHeight) { $y_pos = 0; } else { $y_pos = round( ($staticHeight - $imageHeight) / 2 ); }

            //Copy the source image to the new canvas
            $src = imagecreatefrompng($brands_image_location);
            imagecopy($newimage, $src, $x_pos, $y_pos, 0, 0, $imageWidth, $imageHeight);
            imagepng($newimage,$brands_image_location_tmp);

            // delete the uploaded image
            unlink($brands_image_location);

            // rename the temporary brands image
            rename($brands_image_location_tmp, $brands_image_location);

            // update image metadata and return them
            $image_data['sizes']['brands']['width'] = $staticWidth;
            $image_data['sizes']['brands']['height'] = $staticHeight;

            break;

    }

    return $image_data;
}
like image 147
ChuckMac Avatar answered Nov 16 '22 00:11

ChuckMac


I would like to suggesta change, in order to make it work with Thumbnails Regenerate Plugin

$upload_dir = wp_upload_dir();
$brands_image_location = $upload_dir['basedir'].'/'.dirname($image_data['file']) . '/' . $image_data['sizes']['brands']['file'];
$brands_image_location = $brands_image_location.'.tmp';

That's so because wp_upload_dir returns the path for the current year-month but some previously uploaded images could have different path.

like image 33
Albin Avatar answered Nov 16 '22 02:11

Albin


In my library I have the following:

Set custom name for generated thumbnails

Very interesting manipulation of thumb names and crop. Check the original Q&A linked in this one.

Uses:

  • intermediate_image_sizes_advanced
  • wp_generate_attachment_metadata

Automatically Use Resized Images Instead Of Originals

Uses:

  • wp_generate_attachment_metadata

How to automatically add rounded corners to thumbnails?

Uses:

  • image_make_intermediate_size and L#432

How to Require a Minimum Image Dimension for Uploading?

Uses:

  • wp_handle_upload_prefilter

Organize uploads by year, month and day

Uses:

  • wp_handle_upload_prefilter
  • wp_handle_upload and L#466
  • upload_dir
like image 39
brasofilo Avatar answered Nov 16 '22 01:11

brasofilo