Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2020-12-16 15:52:47 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2020-12-17 11:14:18 +0300
commit3ba147e702a5ae0af6e8b3b0296d256c3246a546 (patch)
treebe78ef8f1a2106bf8816f0a8c4f7872169353691 /resources
parenta2d146ec32a26ccca9ffa68d3c840ec5b08cca96 (diff)
images: Add images.Overlay filter
This allows for constructs ala: ``` {{ $overlay := $img.Filter (images.Overlay $logo 50 50 )}} ``` Or: ``` {{ $logoFilter := (images.Overlay $logo 50 50 ) }} {{ $overlay := $img | images.Filter $logoFilter }} ``` Which will overlay the logo in the top left corner (x=50, y=50) of `$img`. Fixes #8057 Fixes #4595 Updates #6731
Diffstat (limited to 'resources')
-rw-r--r--resources/image.go6
-rw-r--r--resources/image_test.go6
-rw-r--r--resources/images/filters.go8
-rw-r--r--resources/images/image.go6
-rw-r--r--resources/images/overlay.go43
-rw-r--r--resources/resource/resourcetypes.go5
-rw-r--r--resources/testdata/golden/gohugoio24_huc57dd738f4724f4b341121e66fd85555_267952_3ad578dd67cd055b4382e4062918d0a2.pngbin0 -> 61498 bytes
-rw-r--r--resources/testdata/golden/gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_b4afd8d32218a87ed1f7e351368501c3.pngbin0 -> 26664 bytes
-rw-r--r--resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_30x0_resize_box_2.pngbin0 -> 1314 bytes
-rw-r--r--resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_da536a2a5436e387d0d482675e08ad48.jpgbin0 -> 6848 bytes
-rw-r--r--resources/transform.go5
11 files changed, 77 insertions, 2 deletions
diff --git a/resources/image.go b/resources/image.go
index ed303613f..0396c2208 100644
--- a/resources/image.go
+++ b/resources/image.go
@@ -242,7 +242,7 @@ func (i *imageResource) doWithImageConfig(conf images.ImageConfig, f func(src im
errOp := conf.Action
errPath := i.getSourceFilename()
- src, err := i.decodeSource()
+ src, err := i.DecodeImage()
if err != nil {
return nil, nil, &os.PathError{Op: errOp, Path: errPath, Err: err}
}
@@ -324,7 +324,9 @@ func (i *imageResource) decodeImageConfig(action, spec string) (images.ImageConf
return conf, nil
}
-func (i *imageResource) decodeSource() (image.Image, error) {
+// DecodeImage decodes the image source into an Image.
+// This an internal method and may change.
+func (i *imageResource) DecodeImage() (image.Image, error) {
f, err := i.ReadSeekCloser()
if err != nil {
return nil, _errors.Wrap(err, "failed to open image for decode")
diff --git a/resources/image_test.go b/resources/image_test.go
index 9c1861960..8c69591cf 100644
--- a/resources/image_test.go
+++ b/resources/image_test.go
@@ -533,6 +533,11 @@ func TestImageOperationsGolden(t *testing.T) {
fmt.Println(workDir)
}
+ gopher := fetchImageForSpec(spec, c, "gopher-hero8.png")
+ var err error
+ gopher, err = gopher.Resize("30x")
+ c.Assert(err, qt.IsNil)
+
// Test PNGs with alpha channel.
for _, img := range []string{"gopher-hero8.png", "gradient-circle.png"} {
orig := fetchImageForSpec(spec, c, img)
@@ -589,6 +594,7 @@ func TestImageOperationsGolden(t *testing.T) {
f.Invert(),
f.Hue(22),
f.Contrast(32.5),
+ f.Overlay(gopher.(images.ImageSource), 20, 30),
}
resized, err := orig.Fill("400x200 center")
diff --git a/resources/images/filters.go b/resources/images/filters.go
index dd7b58345..74c50363e 100644
--- a/resources/images/filters.go
+++ b/resources/images/filters.go
@@ -25,6 +25,14 @@ const filterAPIVersion = 0
type Filters struct {
}
+// Overlay creates a filter that overlays src at position x y.
+func (*Filters) Overlay(src ImageSource, x, y interface{}) gift.Filter {
+ return filter{
+ Options: newFilterOpts(src.Key(), x, y),
+ Filter: overlayFilter{src: src, x: cast.ToInt(x), y: cast.ToInt(y)},
+ }
+}
+
// Brightness creates a filter that changes the brightness of an image.
// The percentage parameter must be in range (-100, 100).
func (*Filters) Brightness(percentage interface{}) gift.Filter {
diff --git a/resources/images/image.go b/resources/images/image.go
index 88eed2f7e..3d28263c0 100644
--- a/resources/images/image.go
+++ b/resources/images/image.go
@@ -325,3 +325,9 @@ func IsOpaque(img image.Image) bool {
return false
}
+
+// ImageSource identifies and decodes an image.
+type ImageSource interface {
+ DecodeImage() (image.Image, error)
+ Key() string
+}
diff --git a/resources/images/overlay.go b/resources/images/overlay.go
new file mode 100644
index 000000000..780e28fd1
--- /dev/null
+++ b/resources/images/overlay.go
@@ -0,0 +1,43 @@
+// Copyright 2020 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 (
+ "fmt"
+ "image"
+ "image/draw"
+
+ "github.com/disintegration/gift"
+)
+
+var _ gift.Filter = (*overlayFilter)(nil)
+
+type overlayFilter struct {
+ src ImageSource
+ x, y int
+}
+
+func (f overlayFilter) Draw(dst draw.Image, src image.Image, options *gift.Options) {
+ overlaySrc, err := f.src.DecodeImage()
+ if err != nil {
+ panic(fmt.Sprintf("failed to decode image: %s", err))
+ }
+
+ gift.New().Draw(dst, src)
+ gift.New().DrawAt(dst, overlaySrc, image.Pt(f.x, f.y), gift.OverOperator)
+}
+
+func (f overlayFilter) Bounds(srcBounds image.Rectangle) image.Rectangle {
+ return image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy())
+}
diff --git a/resources/resource/resourcetypes.go b/resources/resource/resourcetypes.go
index f42372fa3..206ce8de8 100644
--- a/resources/resource/resourcetypes.go
+++ b/resources/resource/resourcetypes.go
@@ -14,6 +14,8 @@
package resource
import (
+ "image"
+
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/media"
@@ -59,6 +61,9 @@ type ImageOps interface {
Resize(spec string) (Image, error)
Filter(filters ...interface{}) (Image, error)
Exif() *exif.Exif
+
+ // Internal
+ DecodeImage() (image.Image, error)
}
type ResourceTypeProvider interface {
diff --git a/resources/testdata/golden/gohugoio24_huc57dd738f4724f4b341121e66fd85555_267952_3ad578dd67cd055b4382e4062918d0a2.png b/resources/testdata/golden/gohugoio24_huc57dd738f4724f4b341121e66fd85555_267952_3ad578dd67cd055b4382e4062918d0a2.png
new file mode 100644
index 000000000..3a267fbdb
--- /dev/null
+++ b/resources/testdata/golden/gohugoio24_huc57dd738f4724f4b341121e66fd85555_267952_3ad578dd67cd055b4382e4062918d0a2.png
Binary files differ
diff --git a/resources/testdata/golden/gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_b4afd8d32218a87ed1f7e351368501c3.png b/resources/testdata/golden/gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_b4afd8d32218a87ed1f7e351368501c3.png
new file mode 100644
index 000000000..86896ef01
--- /dev/null
+++ b/resources/testdata/golden/gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_b4afd8d32218a87ed1f7e351368501c3.png
Binary files differ
diff --git a/resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_30x0_resize_box_2.png b/resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_30x0_resize_box_2.png
new file mode 100644
index 000000000..5b8748351
--- /dev/null
+++ b/resources/testdata/golden/gopher-hero8_huaa0cd7d2cfc14ff32a57f171896f2285_13327_30x0_resize_box_2.png
Binary files differ
diff --git a/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_da536a2a5436e387d0d482675e08ad48.jpg b/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_da536a2a5436e387d0d482675e08ad48.jpg
new file mode 100644
index 000000000..15f2ef1c5
--- /dev/null
+++ b/resources/testdata/golden/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_da536a2a5436e387d0d482675e08ad48.jpg
Binary files differ
diff --git a/resources/transform.go b/resources/transform.go
index a9ec84671..9007ead18 100644
--- a/resources/transform.go
+++ b/resources/transform.go
@@ -16,6 +16,7 @@ package resources
import (
"bytes"
"fmt"
+ "image"
"io"
"path"
"strings"
@@ -264,6 +265,10 @@ func (r *resourceAdapter) Width() int {
return r.getImageOps().Width()
}
+func (r *resourceAdapter) DecodeImage() (image.Image, error) {
+ return r.getImageOps().DecodeImage()
+}
+
func (r *resourceAdapter) getImageOps() resource.ImageOps {
img, ok := r.target.(resource.ImageOps)
if !ok {