2

Craft provides the very nice TWIG function dataUrl(pathToImg) to inline images in e-mails.

E.g.

<img src="{{ dataUrl('@webroot/assets/img/logo.svg')" />

will base64 encode the image into the src. This also works if you pass in an instance of an asset:

{% set myAsset = craft.assets.id(123).one() %}
<img src="{{ dataUrl(myAsset) }}" />

My question: Does anyone know how to resize the image first, if you pass in an asset?

This does not work:

<img src="{{ dataUrl(myAsset.getUrl({width: 200, height: 200})) }}" />

4 Answers 4

2

Found it, this works:

<img src="{{ dataUrl('@webroot' ~ myAsset.getUrl({width: 200, height: 200}, true)) }}" />

Two important things:

  • prepend the @webroot alias to the myAsset.getUrl(...)
  • set the second parameter of getUrl(...) to true: myAsset.getUrl({...}, true). This ensures that a real file path is returned by getUrl, because the image is transformed immediately on call. This is necessary for the dataUrl function to work. If it is not present, Craft might return a URL pointing to the image transformation controller (which transforms when called for the first time, this might go wrong here).
1
  • It seems this only works with locally-stored images. I'm trying to get it working with remote images on DigitalOcean Spaces, to no avail.
    – Sandwich
    Jan 11 at 20:15
1

One method that comes to my mind is to create an asset configuration in admin panel (Settings -> Assets), where you can create different Image Transform configurations.

For example, I can create an Image Transforms called Thumbnail then set the required dimensions and quality of the image.

Once you create an Image Transforms, you can utilize them with twig template:

myAsset.getUrl('thumbnail')
3
  • Thanks, but the question was how to get a resized image into dataUrl(...) Apr 22, 2021 at 11:40
  • @MatthiasRedl-Mann My apologies - I think I've misunderstood the question
    – Will Kim
    Apr 22, 2021 at 14:44
  • No worries, good that you tried! Apr 22, 2021 at 15:32
1

You can use Asset::setTransform or Asset::copyWithTransform to get (a copy) of the asset object with your transform applied. Then you can pass that into dataUrl().

{# Apply the transform to myAsset directly #}
{% do myAsset.setTransform({width: 200, height: 200}) %}
{{ dataUrl(myAsset)  }}

{# Use this if you need myAsset without the transform later #}
{% set thumb = myAsset.copyWithTransform({width: 200, height: 200}) %}
{{ dataUrl(thumb)  }}
3
  • how would I call the static methods from TWIG? Apr 22, 2021 at 11:59
  • @Matthias Redl-Mann Sorry for the confusion, they're not static methods, that's just a code notation convention. You can call the methods like any other instance method using dot-notation. I updated the code example with working examples for both methods, either of them should work correctly now.
    – MoritzLost
    Apr 23, 2021 at 14:47
  • Looks good, I will try! Apr 23, 2021 at 15:44
0

It’s not possible to get a dataUrl from a resized asset at this time, not even in Craft 4.

There’s already an issue for that: https://github.com/craftcms/cms/discussions/11388.

In an older, closed issue, the reason is explained: https://github.com/craftcms/cms/issues/10108.

It is said to be possible with the Imager X plugin. And there is a dedicated Blur Hash Plugin.

6
  • It is possible, see solution above Mar 26, 2023 at 12:37
  • Are you sure the transformation is used? I tried your solution and I got huge base64 code that obviously was generated from the original image file. Brandonkelly explained in November 2021: «dataUrl() doesn’t support image transforms, and we can’t fix that because the transformed image might not be readily available.» The discussion he asked to open is still open.
    – Moritz
    Mar 27, 2023 at 13:31
  • 1.) Did you use the true as second argument to getUrl? Mar 27, 2023 at 20:06
  • 2.) This is important, since otherwise Brandon is right Mar 27, 2023 at 20:07
  • 3.) I even tried it again for you and took a screenshot: pasteboard.co/rD2lHd4poo7x.png Mar 27, 2023 at 20:08

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.