Delete original image – keep thumbnail?

I’m using a lot of thumbnails but never the original file. To save space, I’d like to prevent the original from being saved on disk but only keep a thumbnail of 100px. How can I do this?

Thanks,
Dennis

Related posts

Leave a Reply

8 comments

  1. add_filter( 'wp_generate_attachment_metadata', 'delete_fullsize_image' );
    function delete_fullsize_image( $metadata )
    {
        $upload_dir = wp_upload_dir();
        $full_image_path = trailingslashit( $upload_dir['basedir'] ) . $metadata['file'];
        $deleted = unlink( $full_image_path );
    
        return $metadata;
    }
    
  2. I foud another solution in the web. It’s based on the one accepted here, but it takes it even further.

    The one, accepted here, removes the main-image and goes on. The solution I found replaces the original image by the image generated for “large”. It just goes on without replacing if this image-resolution is not defined.

    This way it is ensured that every script, relying on the original image, will still work as before – for example the thumnail regeneration.

    http://www.wprecipes.com/how-to-automatically-use-resized-image-instead-of-originals

    EDIT:

    @dalbaeb pointed me to an issue written in the comments on the blog-post. I rewrote the code based on the API instead of the solution provided there. It’s not that much of a difference, but just to use the same function calls as in the API 😉

    function replace_uploaded_image($image_data) {
        // if there is no large image : return
        if (!isset($image_data['sizes']['large'])) return $image_data;
    
        // paths to the uploaded image and the large image
        $upload_dir = wp_upload_dir();
        $uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
        $large_image_filename = $image_data['sizes']['large']['file'];
    
        // Do what wordpress does in image_downsize() ... just replace the filenames ;)
        $image_basename = wp_basename($uploaded_image_location);
        $large_image_location = str_replace($image_basename, $large_image_filename, $uploaded_image_location);
    
        // delete the uploaded image
        unlink($uploaded_image_location);
    
        // rename the large image
        rename($large_image_location, $uploaded_image_location);
    
        // update image metadata and return them
        $image_data['width'] = $image_data['sizes']['large']['width'];
        $image_data['height'] = $image_data['sizes']['large']['height'];
        unset($image_data['sizes']['large']);
    
        // Check if other size-configurations link to the large-file
        foreach($image_data['sizes'] as $size => $sizeData) {
            if ($sizeData['file'] === $large_image_filename)
                unset($image_data['sizes'][$size]);
        }
    
        return $image_data;
    }
    add_filter('wp_generate_attachment_metadata', 'replace_uploaded_image');
    

    EDIT2:

    I had a problem with the code on one client where another size-configuration linked to the large-file. I updated the code accordingly. If you have any kind of problems with it, drop me a mail.

  3. I know this is very old but I still needed to solve this issue, this may have worked for new images when I used it in functions.php but I did have some issues and images becoming unusable and I also couldn’t harness this to update existing images. I had about 2000 existing images I needed to go through them all and make all ofthe old big images smaller. I created a page on the front end that only an admin can access and used this code.

    The big difference here is that instead of deleting the OG image and renaming the ‘large’ image to the OG name. (This did not work for me, I lost quite a few images trying this method) So instead I copied the large image and named the copy the same as the OG image. Hence the big image gets overwritten by the smaller ‘large’ image. Also on the front end, I had to change how the metadata gets updated.

    Test this on individual posts first, be sure this works for you before changing numposts to -1. I stupidly lost about 100 images trying to run the original code without carefully checking the results first.

    FRONT END CODE TO UPDATE EXISTING IMAGES:

    function replace_uploaded_image_frontend($image_data, $attachment_id) {
    
     // if there is no large image : return
      if (!isset($image_data['sizes']['large'])) return $image_data;
    
      // paths to the uploaded image and the large image
      $upload_dir = wp_upload_dir();
      $uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
      $current_subdir = substr($image_data['file'],0,strrpos($image_data['file'],"/"));
      $large_image_location = $upload_dir['basedir'] . '/'.$current_subdir.'/'.$image_data['sizes']['large']['file'];
    
      //Original code was delete OG file and rename the large file to the OG name. This means you no longer have the large size image. So...
      //Instead I want to take the large file and make a copy and overwrite it over the large file.
        $file_to_be_copied = $large_image_location;
        $copied_file_name = $uploaded_image_location;
      //make a copy of the large image and name that the title of the original image
        if (!copy($file_to_be_copied, $copied_file_name)) {
            echo "failed to copy $file...n";
        }  
        fixImageMeta($attachment_id );
    
    }
    
        function fixImageMeta($attach_id) {
    
                $file = get_attached_file($attach_id);
                if (!empty($file)) {
                    $info = getimagesize($file);
                    $meta = array (
                        'width' => $info[0],
                        'height' => $info[1],
                        'hwstring_small' => "height='{$info[1]}' width='{$info[0]}'",
                        'file' => basename($file),
                        'sizes' => array(),         // thumbnails etc.
                        'image_meta' => array(),    // EXIF data
                    );
                    update_post_meta($attach_id, '_wp_attachment_metadata', $meta);
                }
        }
    
    
              $args = array(
            'post_type' => 'exhibitions',
            'p' => 12926,
            'order' => 'DESC',
            /*'date_query'     => array(
                'after' => array(
                    'year'  => 2016,
                    'month' => 2,
                    'day'   => 28,
                ),
                'before' => array(
                    'year'  => 2016,
                    'month' => 6,
                    'day'   => 30,
                ),
            ),*/
            'numberposts' => 1
        );
        $myposts = get_posts($args);
        foreach ($myposts as $mypost){
    
            $attachment_id = get_post_thumbnail_id( $mypost->ID );
            echo '<br>Attach ID: ' . $attachment_id . ' ';
            $unfiltered = false;
            $image_data = wp_get_attachment_metadata( $attachment_id, $unfiltered );
            print_r($image_data);
            replace_uploaded_image_frontend($image_data, $attachment_id);
    
        }
    

    This of course ran into errors several times, I imagine due to some corrupt images. So after trying to go through them all at once and getting errors, I then had to spend some time going through date ranges to be sure I got all of them updated.

    CODE FOR NEW IMAGES, In functions.php

    function replace_uploaded_image($image_data) {
          // if there is no large image : return
      if (!isset($image_data['sizes']['large'])) return $image_data;
    
      // paths to the uploaded image and the large image
      $upload_dir = wp_upload_dir();
      $uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
      $current_subdir = substr($image_data['file'],0,strrpos($image_data['file'],"/"));
      $large_image_location = $upload_dir['basedir'] . '/'.$current_subdir.'/'.$image_data['sizes']['large']['file'];
    
      //Instead I want to take the large file and make a copy and overwrite it over the original file.
        $file_to_be_copied = $large_image_location; 
        $copied_file_name = $uploaded_image_location;
      //make a copy of the large image and name that the title of the original image
        if (!copy($file_to_be_copied, $copied_file_name)) {
            echo "failed to copy $file...n";
        }
    
      // update image metadata and return them
      $image_data['width'] = $image_data['sizes']['large']['width'];
      $image_data['height'] = $image_data['sizes']['large']['height'];
    
      return $image_data;
    }
    add_filter('wp_generate_attachment_metadata','replace_uploaded_image');
    
  4. The answers above don’t seem to work anymore. I slightly modified the code and the example below works for WordPress 5.5

    function replace_uploaded_image($image_data) {
        // if there is no large image : return
        if (!isset($image_data['sizes']['2048x2048'])) return $image_data;
    
        // paths to the uploaded image and the large image
        $upload_dir = wp_upload_dir();
        $uploaded_image_location = dirname($upload_dir['basedir'] . '/' . $image_data['file']) . '/' . $image_data['original_image'];
        
        // delete the uploaded image
        unlink($uploaded_image_location);
    
        unset($image_data['original_image']);
    
        return $image_data;
    }
    add_filter('wp_generate_attachment_metadata', 'replace_uploaded_image');```
    
  5. WordPress disable upload image original

    Tested wordpress 5.6

    By https://stackoverflow.com/questions/41626139/wordpress-removing-original-image-after-resize

    function replace_uploaded_image($image_data) {
          // if there is no large image : return
      if (!isset($image_data['sizes']['large'])) return $image_data;
    
      // paths to the uploaded image and the large image
      $upload_dir = wp_upload_dir();
      $uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
      // $large_image_location = $upload_dir['path'] . '/'.$image_data['sizes']['large']['file']; // ** This only works for new image uploads - fixed for older images below.
      $current_subdir = substr($image_data['file'],0,strrpos($image_data['file'],"/"));
      $large_image_location = $upload_dir['basedir'] . '/'.$current_subdir.'/'.$image_data['sizes']['large']['file'];
    
      // delete the uploaded image
      unlink($uploaded_image_location);
    
      // rename the large image
      rename($large_image_location,$uploaded_image_location);
    
      // update image metadata and return them
      $image_data['width'] = $image_data['sizes']['large']['width'];
      $image_data['height'] = $image_data['sizes']['large']['height'];
      unset($image_data['sizes']['large']);
    
      return $image_data;
    }
    
    add_filter('wp_generate_attachment_metadata','replace_uploaded_image');
    
  6. The problem with the solutions above is that the unlinked image is the scaled image from the ‘big_image_size_threshold’. (since WP 5.3)
    If you add:

    add_filter( 'big_image_size_threshold', '__return_false' );
    

    to your functions.php, the solution works!