Image.Fill Creating an Empty Image? Workaround Needed

I’m using an srcset to keep different image sizes for posts on my home page. This is the idea:

{{ $img := resources.GetMatch .Params.image }}
{{ $x_400 := $img.Fill "400x300 smart" }}
{{ $x_800 := $img.Fill "800x600 smart" }}
{{ $x_1440 := $img.Fill "1440x1080 smart" }}
{{ $x_2560 := $img.Fill "2560x1920 smart" }}
<img src="{{$img.RelPermalink}}" srcset=... $x_400 etc. />

This works fine for the most part. However, not all my original images are the same size, so one of them in particular is smaller than 800px tall, which means that two of the generated images are null. How do I go around this?

A lot of Hugo’s syntax is opaque to me, so it’s a bit difficult to find solutions. For example, is there a way to add a pipe to the $img.Fill or something where it would replace the empty image with the original in that case?

I tried using if statements, but it said I have the wrong number of parameters. {{ if ($img.Width ">=" "400") }} makes sense to me, but obviously not to the parser.

Why is the Fill function returning an empty image file? Is this a bug? How does one work around this?

My repo right now is DenisLabrecque/Denis-Labrecque-Website-2020: Hugo website redesign (github.com) and the markup involved is in layouts/index.html

You can use eq and friends to test for equality (Read See Also section): compare.Eq | Hugo

{{ if eq $cond1 "foo" }}

More about templating: Templating | Hugo


Read here: image.Fill return zero byte image when image is smaller than the dimensions given · Issue #7955 · gohugoio/hugo · GitHub


You are on the right path with the if statements:

{{ if (ge $img.Width "1440") }}
2 Likes

Thanks, got it working; something like this:

              {{ $img := resources.GetMatch .Params.image }}
              
              {{ $x_400 := $img }}
              {{ if and (ge $img.Width "400") (ge $img.Height "300") }}
                 {{ $x_400 := $img.Fill "400x300 Smart" }}
              {{ end }}

              {{ $x_800 := $img }}
              {{ if and (ge $img.Width "800") (ge $img.Height "600" )}}
                 {{ $x_800 := $img.Fill "800x600 Smart" }}
              {{ end }}

              {{ $x_1440 := $img }}
              {{ if and (ge $img.Width "1440") (ge $img.Height "1080") }}
                 {{ $x_1440 := $img.Fill "1440x1080 Smart" }}
              {{ end }}

              {{ $x_2560 := $img }}
              {{ if and (ge $img.Width "2560") (ge $img.Height "1920") }}
                 {{ $x_2560 := $img.Fill "2560x1920 smart" }}
              {{ end }}

The original solution was OK, but moving it to a partial exposed a couple of problems. The main issue was that variables were not scoping properly.

Because Image.Fill does indeed create an empty resource, I got around this by testing whether the new resource has a width. For example:

{{ $x_2560 := $img.Fill "2560x1920 smart" }}
{{ if $x_2560.Width }}{{$x_2560.RelPermalink}} 2560w{{ end }}

This works best and has the added advantage of shortening the code considerably.

See https://github.com/gohugoio/hugo/issues/7955

Should not too har to fix for anyone wanting to get their hands dirty …

1 Like

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