WP is showing wrong image dimensions

The question:

Several times over time I changed sizes of thumbnails WP generate when images are uploaded, always setting bigger size.

Recently I set Thumbnail Width 600px width and Medium size Max Width 1800px.
After several hundred images uploaded I realized that I need to set smaller image sizes, I reduced Medium size from 1800px to 1500px for future uploads.

I know that already uploaded images will stay on disk in bigger resolution, and that is fine by me, I do not need to use any plugin to regenerate thumbs again.

Problem:

Word Press now shows that size for images uploaded before is also 1500px width, even real size is 1800px (for an example it shows 1500px x 1000px for image that is 1800px x 1200px).

I changed few times width of future images in Dashboard > Settings > Media and I figured out that if real dimensions of already uploaded images are bigger than what is now set in Media Settings, WP will say that width of those images is the width that is set in Media Settings, even real dimensions are bigger.

You can see screenshot example here: https://postimg.cc/fScS3WKH

This is code I use to get image and its dimensions.

$medium_image_url = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'medium'); // Featured image medium size

// To show image dimensions   
echo $medium_image_url[1]; // Show width
echo $medium_image_url[2]; // Show height

How to get real image dimension of already uploaded images which dimensions are bigger than one now set in media settings?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

How to get real image dimension of already uploaded images which
dimensions are bigger than one now set in media settings
?

(Note: The italic and bold formatting above was added by me.)

wp_get_attachment_image_src() indeed doesn’t necessarily return the actual width and height of the resized image file, and that the function relies upon the specific image size’s max width and height set via the media settings screen (see wp-admin → Settings → Media).

Sample test case:

  1. I uploaded a 1600px × 1199px image (let’s call it foo-image.jpg), and the Medium image size’s max width was 300px (the default one). So WordPress saved that original image file and generated several thumbnails, and as for the Medium-sized thumbnail, the actual dimension is 300px × 225px and named foo-image-300x225.jpg.

    And wp_get_attachment_image_src() returned 300 (width) and 225 (height) which is the actual dimension.

  2. Then I changed the max width (setting) from 300px to 200px.

    And then wp_get_attachment_image_src() returned 200 (width) and 150 (height).

    And that is not actually wrong, but it’s just not the actual dimension of the actual thumbnail.

So why so, is because wp_get_attachment_image_src() uses image_downsize() which uses image_constrain_size_for_editor() which scales down the actual/default size of an image and which is the function that returns that “wrong” image dimension (1500px × 1000px in your case, and 200px × 150px in the above test case).

But remember, WordPress performs the scaling for a good reason — “This is so that the image is a better fit for the editor and theme.” — copied from the image_constrain_size_for_editor()‘s function reference.

So if you want to retrieve the actual dimension which are saved in a post metadata (see wp_get_attachment_metadata()), you can first, of course use wp_get_attachment_metadata() and access the relevant array items, but a simpler way is using image_get_intermediate_size() — moreover, it includes the image path relative to the uploads directory (wp-content/uploads), and the full image URL:

$thumbnail_id = get_post_thumbnail_id( $post->ID );

$medium_image_data = image_get_intermediate_size( $thumbnail_id, 'medium' );
var_dump( $medium_image_data['width'], $medium_image_data['height'], $medium_image_data['url'] );
/* Sample output:
int(300)
int(225)
string(68) "https://example.com/wp-content/uploads/2021/05/foo-image-300x225.jpg"
*/

// Or using wp_get_attachment_metadata(), assuming that sizes.medium exists:
$image_metadata = wp_get_attachment_metadata( $thumbnail_id );
$medium_image_data = $image_metadata['sizes']['medium'];
var_dump( $medium_image_data['width'], $medium_image_data['height'] );
// here, $medium_image_data['url'] is NULL (it's not set)!

Note though, that the image_get_intermediate_size()‘s function reference says: (formatted for brevity, and $size is the second parameter for the function)

The $size parameter can be an array with the width and height
respectively. If the size matches the ‘sizes’ metadata array for width
and height, then it will be used. If there is no direct match, then
the nearest image size larger than the specified size will be
used.

Method 2

The width and height attributes on the img tag are not there to tell the browser how big the image file is (the intrinsic size), they’re there to tell the browser how big the img tags DOM node is going to be on the page so that it can lay out the page before the file has loaded and avoid an expensive re-calculation of the pages layout. In fact sometimes a mismatch is desirable, e.g. retina images have double the size of their img tag width and height, sometimes even more.

What you’re describing is the expected and optimal behaviour as the code specifies the medium size. WP will use the smallest size that is as large or larger. This avoids upscaling.

If you want it to use the intrinsic size/original size of the uploaded image, or to use the exact image dimensions, then you need to use the full image size, or regenerate the images using WP CLI or a plugin.

If instead you had used wp_get_attachment_image you would have responsive image attributes added, allowing the browser to size things accordingly. You could even pass in an array of width and height instead of medium e.g. [1500, 1000].


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment