gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
73.52k stars 7.38k forks source link

images: Opacity problem with Resize + Padding with PNG output #12536

Open rnwst opened 1 month ago

rnwst commented 1 month ago

What version of Hugo are you using (hugo version)?

$ hugo version
hugo v0.126.1+extended linux/amd64

Does this issue reproduce with the latest release?

Yes.

Report

The images.Padding function currently ignores the transparency setting when padding a PNG image. While the documentation does state 'conversion to WEBP is required to support transparency' (under Other recipes), I can't see a reason why PNG shouldn't be supported, given that it has an alpha channel. For the moment I have resorted to first converting the image to WEBP, then applying transparent padding, and then converting it back to PNG, but this does not feel like an elegant solution.

rnwst commented 1 month ago

It may be worth noting that the images.Overlay function does not require conversion to WEBP and works fine when overlaying two transparent PNGs.

jmooring commented 1 month ago

This works as expected:

{{ with resources.Get "a.png" }}
  {{ $filter := images.Padding 20 "#ff000055" }}
  {{ with . | images.Filter $filter }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
  {{ end }}
{{ end }}

So you must be doing something different. Please provide example.

Here's a minimal example that does not reproduce the problem:

git clone --single-branch -b hugo-github-issue-12536 https://github.com/jmooring/hugo-testing hugo-github-issue-12536
cd hugo-github-issue-12536
hugo server
rnwst commented 1 month ago

Many thanks for putting together the minimal example, that's awesome!

I spent the last 3 hours trying to work out what's going on. While I still have no idea why this is happening, I submitted a PR which hopefully includes some examples that don't work as expected: jmooring/hugo-testing#10

Results seem to be dependent on what size the image is resized to. Problems also seem to go away when using the WEBP format instead of PNG.

jmooring commented 1 month ago

This works as expected (border is ~ 50% opaque blue):

{{ $i := resources.Get "a.jpg" }}
{{ $filters := slice
  (images.Process "resize x200 png")
  (images.Padding 20 "#00f7")
}}
{{ $i = images.Filter $filters $i }}
<img src="{{ $i.RelPermalink }}" width="{{ $i.Width }}" height="{{ $i.Height }}" alt="">

This does not work as expected (border is some other transparent color):

{{ $i := resources.Get "a.jpg" }}
{{ $i = $i.Resize "x200 png" }}
{{ $filters := slice
  (images.Padding 20 "#00f7")
}}
{{ $i = images.Filter $filters $i }}
<img src="{{ $i.RelPermalink }}" width="{{ $i.Width }}" height="{{ $i.Height }}" alt="">

But this (convert to webp using second construct) works fine:

{{ $i := resources.Get "images/a.jpg" }}
{{ $i = $i.Resize "x200 webp" }}
{{ $filters := slice
  (images.Padding 20 "#00f7")
}}
{{ $i = images.Filter $filters $i }}
<img src="{{ $i.RelPermalink }}" width="{{ $i.Width }}" height="{{ $i.Height }}" alt="">

So, for now, use the first construct.

Example:

git clone --single-branch -b hugo-github-issue-12536 https://github.com/jmooring/hugo-testing hugo-github-issue-12536
cd hugo-github-issue-12536
hugo server