Is it possible to change the light exposition of a photo by using Hugo image filters?

Hello, sorry to bother you again :sweat_smile:

I have a hero section on my homepage that has a background image and some white text in front. By keeping the image as it is, the white text over it is almost unreadable.

My wish was to lower the light exposition of the photo by a 20%.
Sorry, I’m not sure if this is the correct name of this effect in English… BTW just imagine to use Photoshop or any other photo manupulation tool, open the image, place over the image a new layer filled in black (#000) and set the opacity of the layer to 80%.
I did it and I obtained this:

Then I said to myself: “Why should I touch my original image, when I can have Hugo do this job for me?”. And then I started toying with the Image filters.
I tried to use some Hugo filters, especially the images.Gamma by writing this code:

{{ $image := "" }}
{{ with resources.Get "folder/image.jpg" }}
    {{ $image = .Fit "1920x1080 q66" }}
    {{ $altered_image = $image.Filter (images.Gamma 0.8) }}
{{ end }}

But by lowering the Gamma to 80% the final result was different from what I hoped for, and instead I got this image:

I also tried to apply different values for images.Brightness and images.Contrast but yet I wasn’t enthusiastic about the final result:

So the difference between that effect applied through Hugo and what I expected to obtain would be this:

And so my question is this…

Is there a filter or some way through Hugo to lower the light exposition of an image?

Thanks in advance

Have you tested the CSS route, e.g. filter: brightness(50%);

Unfortunately If I try to apply a CSS filter on the <li> tag that contains the image, every nested tag inherits that rule on the brightness including the heading and the text that appears over the image:

Schermata 2021-05-14 alle 23.05.19

I suspect you need to apply it to the img tag.

Unfortunately I’m loading the image through the css property background-image in a li tag:

<li class="parallax" style="background-image: url({{ $image.RelPermalink }}); filter: brightness(50%)">
    <div class="flex-caption text-align-center">
        <div class="container">
            <div class="flex-caption-table">
                <div class="flex-caption-cell">
                    <div class="flex-caption-text">
                       <h2>{{ .Title }}</h2>
                       <p>{{ .Content | safeHTML }}</p>
                       ...

You would be better off using an image editor to achieve what you need.

There is also the backdrop-filter property that may give you what you need, but it is not currently supported on Firefox.

1 Like

How to apply a filter to a background image. The trick is to add some elements that get the filter. That website is bookmarkable for everything CSS related :wink:

1 Like

This is not mandatory, you could just as well use an img element. There’s also the CSS property mix-blend-mode that determines how the fore- and background are blended.

Slightly OT, you might consider cleaning up the markup: li - div - div - div - div - div - h2 looks a bit over-engineered to me. Using a div with display: flex might be cleaner. Or <div><img/><div><h2></h2><p></p></div></div>, where the inner div containing the text has a transparent background and is positioned absolutely. In any case, I’d not put styles inside the template.

1 Like

If you are dissatisfied with something like this:

{{ $image := $image.Filter (images.Brightness -25 )}}

or this:

{{ $image := $image.Filter (images.Gamma .7 )}}

then try this:

background: linear-gradient(rgba(0,0,0,.4), rgba(0,0,0,.4)), url({{ $image.RelPermalink }});

or this:

background: radial-gradient(at center 65%, rgba(0,0,0,.6), rgba(0,0,0,.2)), url({{ $image.RelPermalink }});

I like the last one because it lowers the vertical center of the ellipse to where you need it most: behind the smaller text.

3 Likes

Thank you, you and @jmooring gave me the same useful advice. I’m definitely going to try this approach.

This is true, and it also could allow me to either use a jpeg or a webp image instead of relying on modernizr.js

I’ll also try this approach. Thanks.

Thank you. This is also a great advice: As you suggested I could apply a double background via CSS; a solid black semi-transparent background over the other background image.
And I also see that it’s a well supported CSS feature on virtually any browser: https://caniuse.com/multibackgrounds

Realise you already have plenty of options but I’d like to add my personal take, as this type of image effect is something I’ve done a lot of!

  1. As your image has some meaning an inline image is probably more approriate semantically than using the background-image property, as it is not purely decorative. Beyond that an inline image would be better for performance, better for SEO and better for accessibility. This article gives some detailed info on that: https://nystudio107.com/blog/the-css-background-image-property-as-an-anti-pattern

  2. CSS filters are bad for performance and should be considered one of the most ‘expensive’ properties in terms of the cost to cpu utilisation and power consumption, they increase the ‘paint’ time for the browser. Avoid if you care about performance!

Personally, I would create a psuedo element with a solid colour and a reduced opacity and apply that to an element containing the image, as you can’t place a pseudo element on image.

.img-overlay {
   position: relative;
}

.img-overlay::before {
   background-color: rgba(0,0,0,.4);
   bottom: 0;
   content: "";
   display: block;
   left: 0;
   position: absolute;
   right: 0;
   top: 0;
}
2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.