11

There is almost never a reason why I would want an image to be scaled past 100% by a transform. This usually results in an image being looking worse than it would if scaled by the browser. Is there a way to tell Craft not to scale an image past 100% of its original size, even if the transform width is larger?

2

3 Answers 3

10

Yes.

getWidth will give you an image's width: {% set originalWidth = image.getWidth(false) %}. You want to apply the transform if desiredWidth is less than originalWidth. I would write a twig macro:

{% macro transform(image, desiredWidth) %}
  {% set originalWidth = image.getWidth(false) %}
  {% if desiredWidth < originalWidth %}
    {{ image.getUrl({mode: 'fit', width: desiredWidth}) }}
  {% else %}
    {{ image.getUrl() }}
  {% endif %}
{% endmacro %}

You could also do the same test, and then conditionally setTransform on the image.

If you define your transforms in the CP the macro would be like this:

{% macro transform(image, transformHandle) %}
  {% set originalWidth = image.getWidth(false) %}
  {% set transformedWidth = image.getWidth(transformHandle) %}
  {% if transformedWidth < originalWidth %}
    {{ image.getUrl(transformHandle) }}
  {% else %}
    {{ image.getUrl() }}
  {% endif %}
{% endmacro %}
2
  • 3
    Good answer. Would be nice, though, if this was a setting built into Transforms.
    – cmal
    Commented Jul 27, 2014 at 19:26
  • 1
    @cmal it looks like a setting to prevent upscaling is already on "The List".
    – carlcs
    Commented Jul 27, 2014 at 21:43
3

Here's a slight revision that checks widths and heights and ensures that the output has no white space:

{%- macro imageURL(image, transform) -%}
    {% spaceless %}
        {% if image.getWidth > image.getWidth(transform) or image.getHeight > image.getHeight(transform) %}
            {{ image.getUrl(transform) }}
        {% else %}
            {{ image.getUrl }}
        {% endif %}
    {% endspaceless %}
{%- endmacro -%}

Template usage:

{% import "_macros" as utils %}

<img src="{{ utils.imageURL(asset, 'medium') }}">
2

In Craft 3 there's another way of doing it.
Brandon explained it here

{% set transformDimensions = craft.app.assetTransforms.getTransformByHandle('contentWidth') %}
{% set transform = {
    width: min(transformDimensions.width, image.width),
    mode: 'fit'
} %}

<img src="{{ image.url(transform) }}" alt="" />

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.