Fix transparency problem when converting 32-bit images to WebP
Fixes #8729
|
@ -28,6 +28,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/resources/images/webp"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/paths"
|
"github.com/gohugoio/hugo/common/paths"
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
@ -550,6 +552,47 @@ func goldenEqual(img1, img2 *image.NRGBA) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #8729
|
||||||
|
func TestImageOperationsGoldenWebp(t *testing.T) {
|
||||||
|
if !webp.Supports() {
|
||||||
|
t.Skip("skip webp test")
|
||||||
|
}
|
||||||
|
c := qt.New(t)
|
||||||
|
c.Parallel()
|
||||||
|
|
||||||
|
devMode := false
|
||||||
|
|
||||||
|
testImages := []string{"fuzzy-cirlcle.png"}
|
||||||
|
|
||||||
|
spec, workDir := newTestResourceOsFs(c)
|
||||||
|
defer func() {
|
||||||
|
if !devMode {
|
||||||
|
os.Remove(workDir)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if devMode {
|
||||||
|
fmt.Println(workDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, imageName := range testImages {
|
||||||
|
image := fetchImageForSpec(spec, c, imageName)
|
||||||
|
imageWebp, err := image.Resize("200x webp")
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(imageWebp.Width(), qt.Equals, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
if devMode {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dir1 := filepath.Join(workDir, "resources/_gen/images")
|
||||||
|
dir2 := filepath.FromSlash("testdata/golden_webp")
|
||||||
|
|
||||||
|
assetGoldenDirs(c, dir1, dir2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestImageOperationsGolden(t *testing.T) {
|
func TestImageOperationsGolden(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
c.Parallel()
|
c.Parallel()
|
||||||
|
@ -658,6 +701,12 @@ func TestImageOperationsGolden(t *testing.T) {
|
||||||
dir1 := filepath.Join(workDir, "resources/_gen/images")
|
dir1 := filepath.Join(workDir, "resources/_gen/images")
|
||||||
dir2 := filepath.FromSlash("testdata/golden")
|
dir2 := filepath.FromSlash("testdata/golden")
|
||||||
|
|
||||||
|
assetGoldenDirs(c, dir1, dir2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func assetGoldenDirs(c *qt.C, dir1, dir2 string) {
|
||||||
|
|
||||||
// The two dirs above should now be the same.
|
// The two dirs above should now be the same.
|
||||||
dirinfos1, err := ioutil.ReadDir(dir1)
|
dirinfos1, err := ioutil.ReadDir(dir1)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
|
@ -692,7 +741,7 @@ func TestImageOperationsGolden(t *testing.T) {
|
||||||
"gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_300x200_fill_gaussian_smart1_2.png":
|
"gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_300x200_fill_gaussian_smart1_2.png":
|
||||||
c.Log("expectedly differs from golden due to dithering:", fi1.Name())
|
c.Log("expectedly differs from golden due to dithering:", fi1.Name())
|
||||||
default:
|
default:
|
||||||
t.Errorf("resulting image differs from golden: %s", fi1.Name())
|
c.Errorf("resulting image differs from golden: %s", fi1.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
"image/gif"
|
"image/gif"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"image/png"
|
"image/png"
|
||||||
|
@ -236,7 +237,18 @@ func (p *ImageProcessor) ApplyFiltersFromConfig(src image.Image, conf ImageConfi
|
||||||
|
|
||||||
func (p *ImageProcessor) Filter(src image.Image, filters ...gift.Filter) (image.Image, error) {
|
func (p *ImageProcessor) Filter(src image.Image, filters ...gift.Filter) (image.Image, error) {
|
||||||
g := gift.New(filters...)
|
g := gift.New(filters...)
|
||||||
dst := image.NewRGBA(g.Bounds(src.Bounds()))
|
bounds := g.Bounds(src.Bounds())
|
||||||
|
var dst draw.Image
|
||||||
|
switch src.(type) {
|
||||||
|
case *image.RGBA:
|
||||||
|
dst = image.NewRGBA(bounds)
|
||||||
|
case *image.NRGBA:
|
||||||
|
dst = image.NewNRGBA(bounds)
|
||||||
|
case *image.Gray:
|
||||||
|
dst = image.NewGray(bounds)
|
||||||
|
default:
|
||||||
|
dst = image.NewNRGBA(bounds)
|
||||||
|
}
|
||||||
g.Draw(dst, src)
|
g.Draw(dst, src)
|
||||||
return dst, nil
|
return dst, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,3 +28,8 @@ import (
|
||||||
func Encode(w io.Writer, m image.Image, o webpoptions.EncodingOptions) error {
|
func Encode(w io.Writer, m image.Image, o webpoptions.EncodingOptions) error {
|
||||||
return libwebp.Encode(w, m, o)
|
return libwebp.Encode(w, m, o)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Supports returns whether webp encoding is supported in this build.
|
||||||
|
func Supports() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -28,3 +28,8 @@ import (
|
||||||
func Encode(w io.Writer, m image.Image, o webpoptions.EncodingOptions) error {
|
func Encode(w io.Writer, m image.Image, o webpoptions.EncodingOptions) error {
|
||||||
return herrors.ErrFeatureNotAvailable
|
return herrors.ErrFeatureNotAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Supports returns whether webp encoding is supported in this build.
|
||||||
|
func Supports() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
BIN
resources/testdata/fuzzy-cirlcle.png
vendored
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 7.7 KiB |