Understanding image_url options

Short description of issue

I’m looking for more detailed information on how the image_url filter applies width/height/crop options.

Reproduction steps

If I have some liquid like this:

image_url: width: 2048, height: 2048

The docs say this defaults to crop: 'center' behavior, where crop is for “which part of the image to show if the specified dimensions result in an aspect ratio that differs from the original.” The URL it produces seems to match that, since it looks like ...jpg?crop=center&height=2048&width=2048....

But the image itself doesn’t seem to reflect this. My images are 3:2 aspect ratio and much larger than 2048x2048, so I would think this would mean the image would come back as 2048x2048 and cropped. But what I actually get from those URLs is 1365x2048, so, they’re fit into a 2048x2048 bounding box with no cropping applied wait, no, it’s giving me 1000x1500, apparently.

Additional info

As it turns out, the aspect ratio behavior I see is what I want, since it matches the behavior I have from my use of the old img_url filter I’m migrating away from. But… isn’t it supposed to be cropped? Or am I reading the docs wrong? And how are these output dimensions determined? I want to make sure I have a handle on how this “new” filter works.

What type of topic is this

General discussion

I think I see what my issue is. I wasn’t paying enough attention to the test images I was working with, and I was maxing out the actual dimensions of the original data. The docs also say, “Regardless of the specified dimensions, an image can never be resized to be larger than its original dimensions,” and that matches what I’m seeing. If I test with a variety of smaller sizes with image_url it does the cropping just as described, up until it hits a size where one dimension would be larger than the original and then it leaves the aspect ratio as-is.

Testing a bit more, I realize this means I still don’t know how to get the same behavior from image_url I’ve been getting with img_url, though. Previously the width and height specified a bounding box and the output image kept its aspect ratio to fit within that box. But now it’s always cropping.

So for example, with a 1200x920 original image, img_url: '100x100' would actually give me a 100x77 jpeg, but image_url: width: 100, height: 100 gives me a 100x100 jpeg with center cropping. I could specify just one dimension or the other, but whether the remaining dimension ends up bigger or smaller would then depend on whether the original image is landscape or portrait, so it’s not quite the same. Can I still get the old bounding box behavior somehow?

In terms of Liquid used and the resulting image URLs:

img_url: '100x100':                 .../file_100x100.jpg
image_url: width: 100:              .../file.jpg?width=100
image_url: height: 100:             .../filejpg?height=100
image_url: width: 100, height: 100: .../file.jpg?crop=center&height=100&width=100

Looking at all that, I realized I can manually try this:

.../file.jpg?height=100&width=100

…and that does give me a 100x77 px jpeg like the old deprecated filter does. I just don’t know how to get image_url to produce that output.

Hi,

Have you tried specifying the width only so the height is automatically calculated based on the image’s dimensions?

Yep! But that lets the height grow larger than the width (or smaller, whatever the case may be) rather than constraining both dimensions like the URL from img_url can. The key difference to me is that if you give both width and height, the old filter constrains in a bounding box and keeps the original aspect ratio, where the new filter crops and enforces a new aspect ratio.

I realized I can put all of this in a couple concise code blocks to show what I mean and round out what I gave earlier. Stripping out the full path and the v= part for simplicity, these liquid filter calls give URLs like these:

    Liquid                              URL
    img_url: 100x                       file_100x.jpg
    img_url: x100                       file_x100.jpg
    img_url: 100x100                    file_100x100.jpg
    image_url: width: 100               file.jpg?width=100
    image_url: height: 100              file.jpg?height=100
    image_url: width: 100, height: 100  file.jpg?crop=center&height=100&width=100

The actual image dimensions those URLs give you depend on the aspect ratio of the image, but for an example landscape image it gives:

img_url: 100x                       100x77
img_url: x100                       130x100
img_url: 100x100                    100x77
image_url: width: 100               100x77
image_url: height: 100              130x100
image_url: width: 100, height: 100  100x100   ✗ cropped at 1:1

But if I manually remove crop=center in that URL, it works:

(image_url URL but no crop=center)  100x77    ✓ what I want

So the problem for me is, I can’t seem to get the deprecated img_url tag’s behavior that can constrain the image within a specified width and height without cropping. And again, the reason I can’t just leave the height unspecified is that it would let a portrait image be taller than I want.

To make a long story short, I want to make image_url give me a URL that looks like this:

.../file.jpg?height=100&width=100

…but I can’t see how.