Wordpress - Why WordPress automatic cropping all my images?

WordPress by default is designed to generate 3 types of cropping of any uploaded images (Media):

  • Thumbnail (typically 150px × 150px)
  • Medium (typically 300px × 300px)
  • Large (typically 1024px × 1024px)

It's to ensure site speed with different sizes where necessary. So, with uploading the Original image there would be at least 4 files-

  1. The Original File (not-cropped),
  2. Large,
  3. Medium, and
  4. Thumbnail.

As you already know that, from /wp-admin/options-media.php, you can change the default size's dimensions too. So you can still use the default sizes for your custom purpose. But if you still need a new size other than the three, WordPress allows you to add new image sizes too.

Using add_image_size() function with your desired parameter allows you to add new size for your site. Use the function into your functions.php to add your desired image size:

add_image_size( $name, $width, $height, $crop );

Where —
$name : string write the name within single quote, i.e. 'portfolio'
$width: integer write the width you want, i.e. 500 (in px)
$height: integet write the height you want, i.e. 300 (in px)
$crop: boolean write true if you want to hard-crop the image, otherwise use false

Typically we can call different Featured Image into any place of our theme by using:

the_post_thumbnail( 'medium' ); //it will display only the medium size of the original image

If you want to use your new size, use:

the_post_thumbnail( 'portfolio' ); //as I named my size as 'portfolio'

WARNING: As, by default WordPress is generating 3 customizable image sizes, it's creating 4 files for each images. Using more new sizes will increase the number of files into your site host. So, using more image sizes will be a matter for your site's host-space issue— it'll consume more site spaces.

EDIT

And after adding every new image size, a most important plugin is:

» Regenerate Thumbnail — WordPress Plugin

In reality the newly assigned image size can be available only into newly uploaded images. So, to get the new size for all the previously uploaded images too, you will need the plugin to be installed and regenerate all the thumbnails again. It'd be one-time measure that would last forever*.

And your main answer should be:
Site Speed: WordPress crops images to increase site speed. If you use Google PageSpeed, you'll be known that it suggests:

Serve scaled images
Properly sizing images can save many bytes of data.
Learn More

EDIT 2

As you are already suggested, if your plugin use a similar add_image_size() function, it can create a new image size. So after disabling your plugins, if you use the Regenerate Thumbnails plugin to regenerate the thumbnails, then you will get the actual sizes. If that doesn't help, then check your theme's functions.php or any added functions file for such add_image_size() function, and now you know what to do.


Yes, WordPress resizes & crops all images depending on what your theme defined as @Gerard already explained in his answer. So the last boolean argument for add_image_size() is to crop or not. Note that this doesn't define the crop position. To alter that behavior look at this answer for example.

What happens inside core?

As you've already seen in the source of add_image_size(), WP uses the global $_wp_additiona_image_sizes to store & handle the settings for your image generation. Now, when you upload an image, the class WP_Image_Editor comes into game and - depending on the PHP extensions enabled on your server - either calls WP_Image_Editor_GD or WP_Image_Editor_Imagick. Now both Singletons have a resize() method which calls image_resize_dimensions(). At the end, image_resize_dimensions() does not resize or crop the image. It just calculates the values.

This is done by the method crop() in the Imagick class and by using PHPs native imagecopyresampled() inside the GD class.

How to disable cropping?

First, we have lots of possibilities:

  • detect which class is in use (which PHP ext. is supported) and then intercept whatever is used to crop (see above).
  • Short circuit the whole process and let image_resize_dimensions() do it's work.

We'll use the later method in here. Feel free to add your own solution as separate answer. Here's what core offers us: A filter holding all parameters.

$output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); 

Now the first argument is null, which tells core on the next line if we want to overwrite what this function does internally - and replace it with our own behavior - or not. So if we'd return anything aside from null, then this is what core will use. Keep in mind that you can put anything there, but still core will expect the same return value as image_resize_dimensions() uses per default. From the inline comments:

The return array matches the parameters to imagecopyresampled():

int dst_x, int dst_y,

int src_x, int src_y,

int dst_w, int dst_h,

int src_w, int src_h

Now to just disable crop we'd have to replace (in other words: clone) the whole internals - something that we want to avoid. Therefore we're using a "one time filter" that disables itself. We're doing that to use the internals, but just get rid of what we don't need.

<?php
defined( 'ABSPATH' ) or exit;
/* Plugin Name: (#124009) Disable image crop */

add_filter( 'image_resize_dimensions', 'wpse124009DisableCrop', 10, 6 );
function wpse124009DisableCrop( $enable, $orig_w, $orig_h, $dest_w, $dest_h, $crop )
{
    // Instantly disable this filter after the first run
    remove_filter( current_filter(), __FUNCTION__ );

    return image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, false );
}

Now cropping is disabled everywhere. If you're running multisite or you don't want to think about if this plugin is enabled, simply go and use it as a mu-plugin.

Please keep in mind that above is not tested, but written off of my head after reading core source.

Additional info

More info about the image handling classes in the slides of Marko from WordCamp Europe and the video of the presentation can be found on WordPress.tv.


Normally it is because a Wordpress theme uses the thumbnails on its code: in loops, galleries, etc. It is defined in the file functions.php:

add_image_size( $name, $width, $height, $crop );

For example, like this:

add_theme_support('post-thumbnails');
add_image_size('custom-thumbnail', 80, 80, true );
add_image_size('medium-thumbnail', 180, 120, true );
add_image_size('large-thumbnail', 571, 300, true );

I don't recommend you to remove the code if you really want to keep the good working of your theme. If you want to remove it, you will need to delete the calls in the other files where it is used; commonly in the file loop.php.