How To Hook Into WordPress Thumbnail Generation

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:

Read More
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!

Related posts

Leave a Reply

3 comments

  1. 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;
    }
    
  2. 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.