URI: 
       Add images.Opacity filter - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit f9b3c0f4860d2664d2abf0513ee8055a37a7fdd5
   DIR parent 11fcda971c716cb63764c4e54026d0916311fe23
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Thu, 21 Sep 2023 22:32:32 +0200
       
       Add images.Opacity filter
       
       Fixes #11471
       
       Diffstat:
         M docs/content/en/functions/images/i… |      13 +++++++++++++
         M resources/image_test.go             |      26 ++++++++++++++------------
         M resources/images/filters.go         |      12 ++++++++++--
         A resources/images/opacity.go         |      39 +++++++++++++++++++++++++++++++
         A resources/testdata/golden/gopher-h… |       0 
         A resources/testdata/golden/gradient… |       0 
         A resources/testdata/golden/sunset_h… |       0 
         A resources/testdata/golden/sunset_h… |       0 
       
       8 files changed, 76 insertions(+), 14 deletions(-)
       ---
   DIR diff --git a/docs/content/en/functions/images/index.md b/docs/content/en/functions/images/index.md
       @@ -34,6 +34,19 @@ A shorter version of the above, if you only need to apply the filter once:
        
        The above will overlay `$logo` in the upper left corner of `$img` (at position `x=50, y=50`).
        
       +## Opacity
       +
       +{{% funcsig %}}
       +images.Opacity SRC OPACITY
       +{{% /funcsig %}}
       +
       +Opacity creates a filter that changes the opacity of an image.
       +The OPACITY parameter must be in range (0, 1).
       +
       +```go-html-template
       +{{ $img := $img.Filter (images.Opacity 0.5 )}}
       +```
       +
        ## Text
        
        Using the `Text` filter, you can add text to an image.
   DIR diff --git a/resources/image_test.go b/resources/image_test.go
       @@ -63,7 +63,7 @@ var eq = qt.CmpEquals(
                        }
                        return p1.Name() == p2.Name() && p1.Size() == p2.Size() && p1.IsDir() == p2.IsDir()
                }),
       -        //cmp.Comparer(func(p1, p2 *genericResource) bool { return p1 == p2 }),
       +        // cmp.Comparer(func(p1, p2 *genericResource) bool { return p1 == p2 }),
                cmp.Comparer(func(m1, m2 media.Type) bool {
                        return m1.Type == m2.Type
                }),
       @@ -162,7 +162,6 @@ func TestImageTransformBasic(t *testing.T) {
                croppedAgain, err := image.Crop("300x300 topRight")
                c.Assert(err, qt.IsNil)
                c.Assert(cropped, qt.Equals, croppedAgain)
       -
        }
        
        func TestImageTransformFormat(t *testing.T) {
       @@ -267,7 +266,6 @@ func TestImageBugs(t *testing.T) {
                        c.Assert(resized, qt.Not(qt.IsNil))
                        c.Assert(resized.Width(), qt.Equals, 100)
                        c.Assert(resized.RelPermalink(), qt.Equals, "/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_c876768085288f41211f768147ba2647.jpg")
       -
                })
        
                // Issue #6137
       @@ -278,7 +276,6 @@ func TestImageBugs(t *testing.T) {
                        c.Assert(err, qt.IsNil)
                        c.Assert(resized, qt.Not(qt.IsNil))
                        c.Assert(resized.Width(), qt.Equals, 200)
       -
                })
        
                // Issue #7955
       @@ -307,9 +304,7 @@ func TestImageBugs(t *testing.T) {
                                        c.Assert(resized.Width(), qt.Equals, test.targetWH)
                                        c.Assert(resized.Height(), qt.Equals, test.targetWH)
                                })
       -
                        }
       -
                })
        }
        
       @@ -613,7 +608,6 @@ func TestImageOperationsGoldenWebp(t *testing.T) {
                dir2 := filepath.FromSlash("testdata/golden_webp")
        
                assetGoldenDirs(c, dir1, dir2)
       -
        }
        
        func TestImageOperationsGolden(t *testing.T) {
       @@ -621,7 +615,7 @@ func TestImageOperationsGolden(t *testing.T) {
                c.Parallel()
        
                // Note, if you're enabling this on a MacOS M1 (ARM) you need to run the test with GOARCH=amd64.
       -        // GOARCH=amd64 go test -timeout 30s -run "^TestImageOperationsGolden$" ./resources -v
       +        // GOARCH=amd64 go test -count 1 -timeout 30s -run "^TestImageOperationsGolden$" ./resources -v
                // The above will print out a folder.
                // Replace testdata/golden with resources/_gen/images in that folder.
                devMode := false
       @@ -644,6 +638,10 @@ func TestImageOperationsGolden(t *testing.T) {
                gopher, err = gopher.Resize("30x")
                c.Assert(err, qt.IsNil)
        
       +        f := &images.Filters{}
       +
       +        sunset := fetchImageForSpec(spec, c, "sunset.jpg")
       +
                // Test PNGs with alpha channel.
                for _, img := range []string{"gopher-hero8.png", "gradient-circle.png"} {
                        orig := fetchImageForSpec(spec, c, img)
       @@ -653,7 +651,15 @@ func TestImageOperationsGolden(t *testing.T) {
                                rel := resized.RelPermalink()
        
                                c.Assert(rel, qt.Not(qt.Equals), "")
       +
                        }
       +
       +                // Check the Opacity filter.
       +                opacity30, err := orig.Filter(f.Opacity(30))
       +                c.Assert(err, qt.IsNil)
       +                overlay, err := sunset.Filter(f.Overlay(opacity30.(images.ImageSource), 20, 20))
       +                rel := overlay.RelPermalink()
       +                c.Assert(rel, qt.Not(qt.Equals), "")
                }
        
                // A simple Gif file (no animation).
       @@ -699,8 +705,6 @@ func TestImageOperationsGolden(t *testing.T) {
                                c.Assert(rel, qt.Not(qt.Equals), "")
                        }
        
       -                f := &images.Filters{}
       -
                        filters := []gift.Filter{
                                f.Grayscale(),
                                f.GaussianBlur(6),
       @@ -746,11 +750,9 @@ func TestImageOperationsGolden(t *testing.T) {
                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.
                dirinfos1, err := os.ReadDir(dir1)
                c.Assert(err, qt.IsNil)
   DIR diff --git a/resources/images/filters.go b/resources/images/filters.go
       @@ -28,8 +28,7 @@ import (
        // Increment for re-generation of images using these filters.
        const filterAPIVersion = 0
        
       -type Filters struct {
       -}
       +type Filters struct{}
        
        // Overlay creates a filter that overlays src at position x y.
        func (*Filters) Overlay(src ImageSource, x, y any) gift.Filter {
       @@ -39,6 +38,15 @@ func (*Filters) Overlay(src ImageSource, x, y any) gift.Filter {
                }
        }
        
       +// Opacity creates a filter that changes the opacity of an image.
       +// The opacity parameter must be in range (0, 1).
       +func (*Filters) Opacity(opacity any) gift.Filter {
       +        return filter{
       +                Options: newFilterOpts(opacity),
       +                Filter:  opacityFilter{opacity: cast.ToFloat32(opacity)},
       +        }
       +}
       +
        // Text creates a filter that draws text with the given options.
        func (*Filters) Text(text string, options ...any) gift.Filter {
                tf := textFilter{
   DIR diff --git a/resources/images/opacity.go b/resources/images/opacity.go
       @@ -0,0 +1,39 @@
       +// Copyright 2023 The Hugo Authors. All rights reserved.
       +//
       +// Licensed under the Apache License, Version 2.0 (the "License");
       +// you may not use this file except in compliance with the License.
       +// You may obtain a copy of the License at
       +// http://www.apache.org/licenses/LICENSE-2.0
       +//
       +// Unless required by applicable law or agreed to in writing, software
       +// distributed under the License is distributed on an "AS IS" BASIS,
       +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       +// See the License for the specific language governing permissions and
       +// limitations under the License.
       +
       +package images
       +
       +import (
       +        "image"
       +        "image/color"
       +        "image/draw"
       +
       +        "github.com/disintegration/gift"
       +)
       +
       +var _ gift.Filter = (*opacityFilter)(nil)
       +
       +type opacityFilter struct {
       +        opacity float32
       +}
       +
       +func (f opacityFilter) Draw(dst draw.Image, src image.Image, options *gift.Options) {
       +        // 0 is fully transparent and 255 is opaque.
       +        alpha := uint8(f.opacity * 255)
       +        mask := image.NewUniform(color.Alpha{alpha})
       +        draw.DrawMask(dst, dst.Bounds(), src, image.Point{}, mask, image.Point{}, draw.Over)
       +}
       +
       +func (f opacityFilter) Bounds(srcBounds image.Rectangle) image.Rectangle {
       +        return image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy())
       +}
   DIR diff --git a/resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_filter_10590793696706257122.png b/resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_filter_10590793696706257122.png
       Binary files differ.
   DIR diff --git a/resources/testdata/golden/gradient-circle_huf3d35257a40a8d6f525263a856c5ecfd_20069_filter_10590793696706257122.png b/resources/testdata/golden/gradient-circle_huf3d35257a40a8d6f525263a856c5ecfd_20069_filter_10590793696706257122.png
       Binary files differ.
   DIR diff --git a/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_filter_16531506165985954191.jpg b/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_filter_16531506165985954191.jpg
       Binary files differ.
   DIR diff --git a/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_filter_18171945436439920693.jpg b/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_filter_18171945436439920693.jpg
       Binary files differ.