Cms: Image transforms have option not to 'scale up'

Created on 31 Jan 2017  ยท  9Comments  ยท  Source: craftcms/cms

Created by: Adam Menczykowski ([email protected]) on 2015/10/01 07:35:28 +0000
Votes at time of UserVoice import: 42


If a user uploads an image that is smaller than the image transform setting, it scales the image up for them to the specified size. However this results in a pixellated image because of the upscale.

What I would like to be able to do is only scale down images to the respective transform values, but if smaller, then keep their size, thus avoiding the pixellation and extra unnecessary file size.

assets enhancement

Most helpful comment

After talking this through, weโ€™ve realized there is no good justification for the current behavior of upscaling smaller images to match the crop constraints. And since there are back-end and web performance benefits to _not_ upscaling images, we think it would be better to simply change the behavior so smaller images are _never_ upscaled, rather than making it something you have to opt into.

That will potentially cause some layout issues wherever transformed images are getting displayed without width or height attributes/CSS styles though. So for now we will add an upscaleImages config setting that is true by default, but overridden to false in config/general.php for new Craft projects, and we will either default the config setting to false for everyone in Craft 4, or just remove it entirely.

All 9 comments

We may add this, but in the meantime, to prevent a transform from scaling the image beyond its size, you can set the target width/height dynamically:

{% set transform = {
    width: min(150, image.width),
    height: min(100, image.height)
} %}

<img src="{{ image.getUrl(transform) }}">

Ooooooh, I've never seen this dynamic setting of target width/height before! Very clever :)

I like Brandon's snipplet, but still a "noUpscale" Option would be great! +1

+1 for this feature request. Image resizing in other CMS we've used automatically leaves images alone unless they are too large and actually need resizing & that's exactly what we need in 99% of cases. Thanks.

We may add this, but in the meantime, to prevent a transform from scaling the image beyond its size, you can set the target width/height dynamically:

{% set transform = {
    width: min(150, image.width),
    height: min(100, image.height)
} %}

<img src="{{ image.getUrl(transform) }}">

Hi brandon,
If I define an image transform in the backend that is called e.g. "contentWidth".
How would this "snipplet" work with it?
Can you output an image transforms width in a template?

I'am all for a config setting: "upscaleImageTransforms" => false, or something similar.

@outline4 You could fetch it via getTransformByHandle():

{% set contentWidth = craft.app.assetTransforms.getTransformByHandle('contentWidth') %}

{% set transform = {
    width: min(contentWidth.width, image.width),
    height: min(contentWidth.height, image.height)
} %}

After talking this through, weโ€™ve realized there is no good justification for the current behavior of upscaling smaller images to match the crop constraints. And since there are back-end and web performance benefits to _not_ upscaling images, we think it would be better to simply change the behavior so smaller images are _never_ upscaled, rather than making it something you have to opt into.

That will potentially cause some layout issues wherever transformed images are getting displayed without width or height attributes/CSS styles though. So for now we will add an upscaleImages config setting that is true by default, but overridden to false in config/general.php for new Craft projects, and we will either default the config setting to false for everyone in Craft 4, or just remove it entirely.

Also, for images that are smaller than one/both of the crop constraints, we will ensure that the resulting transform has the same ratio as the crop constraints (per #5288).

         โ” โ” โ” โ” โ” โ” โ” โ” โ” โ”                            โ” โ” โ” โ” โ” โ” โ” โ” โ” โ”          
                            โ”ƒ                                              โ”ƒ         
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‹โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‹โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           โ”ƒ        โ”‚         โ”‚xxxxxxxxxxxxโ”‚          โ”‚xxxโ”ƒxxxxxxxxโ”‚
โ”‚        โ”ƒ                           โ”‚  โ”€โ”€โ”€โ”€โ–ถ  โ”‚xxxxxxxxโ”ƒxxxโ”‚          โ”‚xxxxxxxxxxxxโ”‚
โ”‚                           โ”ƒ        โ”‚         โ”‚xxxxxxxxxxxxโ”‚          โ”‚xxxโ”ƒxxxxxxxxโ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‹โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‹โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”ƒ                                              โ”ƒ         
         โ”— โ” โ” โ” โ” โ” โ” โ” โ” โ”                            โ”— โ” โ” โ” โ” โ” โ” โ” โ” โ”          

Just a clarification for anyone confused by this like I just was... if upscaling is turned off, and you try to transform an image to a size larger than native, _the transformed result will still be stored in the named subdirectory for that transform_.

So transforming a 400x400px image in /images/ to 1600x800 will result in a 400x200 image, stored in the /images/_1600x1200_crop_center-center_none/ subdirectory.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timkelty picture timkelty  ยท  3Comments

leigeber picture leigeber  ยท  3Comments

angrybrad picture angrybrad  ยท  3Comments

bitboxfw picture bitboxfw  ยท  3Comments

richhayler picture richhayler  ยท  3Comments