Error with imageConfig: image: unknown format

Hi,

I’m using browser-native lazy-loading, and I’m trying to use hugo’s markdown render hooks, render-image.html here, to set the img tag’s width and height attributes, so images don’t push text around when they get downloaded.

However, I keep getting the following error with many pictures:

error calling imageConfig: image: unknown format

The error occurs with both .png and .jpg images. Here’s the template code:

{{ $width := 0 }}
{{ $height := 0 }}

{{ $path := add .Page.RelPermalink (.Destination | safeURL) }}
{{ if not (fileExists $path) }}
    {{ $path = add "/static" (.Destination | safeURL) }}
{{ end }}
{{ warnf "%q" $path }}

{{ if (fileExists $path) }}
    {{ $fullPath := $path }}
    {{ if not (findRE "^/?static" $path 1) }}
        {{ $fullPath = add "/content" $fullPath }}
    {{ end }}

    {{ if ne $fullPath "image" }}
    {{ warnf "%q" $fullPath }}
    {{ with (imageConfig $fullPath) }}
        {{ $width = .Width }}
        {{ $height = .Height }}
    {{ end }}
    {{ end }}
{{ else }}
    {{ warnf "<img/> render hook: %q not found" $path }}
{{ end }}


<img
    src="{{ .Destination | safeURL }}"
    alt="{{ .Text }}"
    loading="lazy"
    {{ if ne $width 0 }}width="{{ $width }}"{{ end }}
    {{ if ne $height 0 }}height="{{ $height }}"{{ end }}
    {{ with .Title}}title="{{ . }}"{{ end }}
/>

And the paths output by the warnf call:

WARN 2020/10/22 14:07:24 "/news/2017/10/godot-3-alpha-attack-tutorial/img/echo86/logo.png"
WARN 2020/10/22 14:07:24 "/content/news/2017/10/godot-3-alpha-attack-tutorial/img/echo86/logo.png"
WARN 2020/10/22 14:07:24 "/news/2017/10/godot-3-alpha-attack-tutorial/img/randa-meetings/konqi-randa.png"
WARN 2020/10/22 14:07:24 "/content/news/2017/10/godot-3-alpha-attack-tutorial/img/randa-meetings/konqi-randa.png"
Built in 615 ms
Error: Error building site: "/home/gdquest/Repositories/website/layouts/_default/_markup/render-image.html:18:13": execute of template failed: template: _default/_markup/render-image.html:18:13: executing "_default/_markup/render-image.html" at <imageConfig $fullPath>: error calling imageConfig: image: unknown format

I started this website (https://www.gdquest.com/) years ago, when hugo had way fewer features, and so I have hundreds of pictures. Back then, I would compress them before adding them to the website, as image processing features weren’t in yet.

As imageConfig doesn’t say which image is faulty, I’m unsure how to pinpoint the pictures that cause trouble and why.

Do you have an idea of how I could further troubleshoot this and get rid of the error?

Note I’d gladly pay someone to help tackle this task. You can find the corresponding issue here on GitHub: https://github.com/GDQuest/website/issues/228 (the website’s open-source). If you’re interested, you can contact me on twitter.

Thank you for your time,
Nathan

Just a guess: I think, it’s because your images are in static. Files in static are not processed by Hugo. That’s my 2 cents.

EDIT 1: Oops, my bad. Looks like, you’re already changing your static path to the content path.

EDIT 2: I can also see that you’re declaring the variable $fullPath multiple times. Are you sure that’s a correct syntax? From what I know, you can’t redeclare a variable in Hugo due to Go’s limitations and you need to use {{ .Scratch }}. See here: [solved] Unsure how to set variable value after declaring

I think you would get a much easier situation if you mount those files inside /assets (you can mount files in multiple locations) and then use resources.Get and friends to get those images.

Regarding variables, that’s not redefining. I define it once and then assign it a new value if a condition is met. It used not to work years ago but it’s been supported for a while now.

Thanks much for the tips, I’ll look into this. Do you have an open-source project that uses the feature, so I could look at how it’s used? I looked into modules and vendored a theme for a section of our website but it’s a little abstract to me.

You would do something like:

[module]
  [[module.mounts]]
    source = "static/img"
    target = "assets/img"

and then instead of the fileExists block, something like:

{{ $resourcePath := .Destination | strings.TrimPrefix "/" }}
{{ $resource := resources.Get $resourcePath }}
$resource: {{$resource}}
{{ with $resource }} <!-- exists in static / assets -->
{{.Width}} / {{.Height}}
{{ end }}

Thanks for the help, the code’s much simpler now! However, I still get errors that some resource is a genericResource and not an image.

Here’s the new render-image.html code:

{{ $image := .Page.Resources.GetMatch .Destination }}
{{ if not $image }}
    {{ $image = resources.Get .Destination }}
{{ end }}

{{ with $image }}
{{ warnf "%q" .Permalink }}
<img
    src="{{ .Permalink }}"
    alt="{{ .Title }}"
    loading="lazy"
    width="{{ .Width }}"
    height="{{ .Height }}"
    {{ with .Title}}title="{{ . }}"{{ end }}
/>
{{ end }}

And the output:

# [...]
WARN 2020/10/22 22:21:08 "//localhost:1313/docs/guidelines/best-practices/making-videos/img/pointer-arrow-demo.png"
WARN 2020/10/22 22:21:08 "//localhost:1313/docs/guidelines/best-practices/making-videos/img/template-arrow-select.png"
Built in 737 ms
Error: Error building site: "/home/gdquest/Repositories/website/layouts/_default/_markup/render-image.html:11:14": execute of template failed: template: _default/_markup/render-image.html:11:14: executing "_default/_markup/render-image.html" at <.Width>: error calling Width: *resources.genericResource is not an image

All the paths output by warnf correspond to pictures that I can find in the public directory, from my last build. They all open in an image editing program.

Any idea of what might be causing this or where I should dig?

Have a read through this topic: How do I turn a genericResource into an image? to see if it’s any help.

Edit:

It may be your svg images:

{{ with $image }}
{{ if (eq .MediaType.SubType "svg") }}
  {{ warnf "%q" .Permalink }}
{{ else }}
  {{ .ResourceType }} || {{ .MediaType.SubType}} || {{.Width}}
{{ end }}
{{ end }}

Also: https://github.com/gohugoio/hugo/issues/3700

I would suggest to allow for a fallback to use the .Destination as is, if no resource is found. It’s a workaround for your particular case, but it won’t fail if using an external URL for your images.

I made a partial using a similar approach recently, it may be helpful: https://github.com/Arty2/onion/blob/master/layouts/partials/render-image.html

Thanks much for the help!

This is starting to look like a bug. I used @Heracles’s partial as a base, and added type checks to ensure that a resource is an image. I tried printing the svg or other image types apart as well using @pointyfar’s snippet but the error persists even if I filter them out.

{{ with $resource  }}
    {{ if eq .ResourceType "image" }}
        {{ warnf "%q %s" . .ResourceType }}
...

Which gives me the output:

# ...
WARN 2020/10/23 08:31:38 "img/key-mon.png" image
WARN 2020/10/23 08:31:38 "img/pointer-arrow-demo.png" image
WARN 2020/10/23 08:31:38 "img/template-arrow-select.png" image
Built in 672 ms
Error: Error building site: "/home/gdquest/Repositories/website/layouts/_default/_markup/render-image.html:18:18": execute of template failed: template: _default/_markup/render-image.html:18:18: executing "_default/_markup/render-image.html" at <.Width>: error calling Width: *resources.genericResource is not an image

All resources are of type image. I tried to remove the lines that trigger errors and run

hugo server -D --ignoreCache | grep -v image

to filter out all resources of type image and see if there’s anything that’s not recognized as an image, it doesn’t show any resource. But the code fails as soon as I try to get .Width or .Height on the resource.

I left this issue for a while to work on more important features, but got back to it yesterday and finally got the hang of it.

Here were the problems, and here’s the solution:

  1. I had to mount the static folder to assets/ as suggested by @bep to be able to get all images as resources
  2. You have to be careful about some types, like for example if you call safeURL on a path the returned object isn’t a string, so you can’t pass it to .Page.Resources.GetMatch
  3. I had to use the .Page object to get resources.
  4. Trying to evaluate width and height on an SVG resource fails. We use some SVGs in Markdown, as we sometimes use the format for lightweight game sprites and other graphic design.

Our website uses a ton of page-related images. Every post or tutorial comes with its own pictures, so the solutions I saw online, which sometimes rely on having everything in the static/ directory, didn’t work for me.

Here’s the final code, which seems to be working like a charm!

{{ $path := .Destination | safeURL }}
{{ $alt := .Text }}
{{ $resource := .Page.Resources.GetMatch .Destination }}

{{ with $resource }}
     {{ if and (eq .ResourceType "image") (ne .MediaType.SubType "svg") }}
     <img src="{{ .Permalink | safeURL }}"
          alt="{{ $alt }}"
          {{ with .Title}}title="{{ . }}"{{ end }}
          {{ with .Width }}width="{{ . }}"{{ end }}
          {{ with .Height }}height="{{ . }}"{{ end }}
     />
     {{ else }}
     <img src="$path" alt="$alt" />
     {{ end }}
{{ end }}

And the relevant mounts config.

[[module.mounts]]
source = "static/img"
target = "assets/img"

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