craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.28k stars 635 forks source link

Can't get `dataUrl( transformedImage )` to work as expected #10108

Closed proimage closed 2 years ago

proimage commented 2 years ago

Description

I'm trying to base64-encode a transformed image asset (an LQIP—low-quality image placeholder), but I can't get it to work:

{# source image is 2560px square #}
{% set img = entry.image.one() %}
{% do img.setTransform({ width: 1280 }) %}
{% set lqip = img %}
{% do lqip.setTransform({ width: 20 }) %}
{{ dataUrl(lqip) }}

The resulting string is a base64-encoded image with the same dimensions as the source image, in this case, 2560px square.

Steps to reproduce

  1. Put the above code into a template
  2. Load it up in a browser
  3. Scroll right for a while because the encoded string is ridiculously long.

Additional info

brandonkelly commented 2 years ago

dataUrl() doesn’t support image transforms, and we can’t fix that because the transformed image might not be readily available.

proimage commented 2 years ago

Ahh, I see... because template render requests don't trigger image transform creation, only the URL that will create the image transform(s), right? And Imager X, for example, can create base64-encoded image transforms when a template is rendered because unlike Craft, it does generate image transforms at that stage (thus bogging down the render pipeline)?

brandonkelly commented 2 years ago

Ahh, I see... because template render requests don't trigger image transform creation, only the URL that will create the image transform(s), right?

By default yes. (Configurable via generateTransformsBeforePageLoad but we can’t rely on that being true.)

Not sure how Imager X works.

proimage commented 2 years ago

So wait, since that setting exists, is it possible to add a parameter to dataUrl() that will force it to generate the transform being passed to it? Something like this?

{# source image is 2560px square #}
{% set img = entry.image.one() %}
{% do img.setTransform({ width: 1280 }) %}
{% set lqip = img %}
{% do lqip.setTransform({ width: 20 }) %}
{{ dataUrl(lqip, forceTransformGeneration = true) }}
brandonkelly commented 2 years ago

Perhaps but it would also require us to update getContent() and would be a breaking change. Will look into it for Craft 4.

proimage commented 2 years ago

Ok, you certainly know better than I do. ;) Thanks BK!

proimage commented 2 years ago

With Craft 4 out, is this now possible?

brandonkelly commented 2 years ago

Sorry, we didn’t manage to get to this in 4.0. Still on the list though. Do you mind creating a discussion for this instead though?

proimage commented 2 years ago

Done: https://github.com/craftcms/cms/discussions/11388