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>2019-08-26 20:12:41 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-08-28 16:59:54 +0300
commit823f53c861bb49aecc6104e0add39fc3b0729025 (patch)
tree64a55d1c41de09b67305ad69a3600f3091d4f1fc /resources/image.go
parentf9978ed16476ca6d233a89669c62c798cdf9db9d (diff)
Add a set of image filters
With this you can do variants of this: ``` {{ $img := resources.Get "images/misc/3-jenny.jpg" }} {{ $img := $img.Resize "300x" }} {{ $g1 := $img.Filter images.Grayscale }} {{ $g2 := $img | images.Filter (images.Saturate 30) (images.GaussianBlur 3) }} ``` Fixes #6255
Diffstat (limited to 'resources/image.go')
-rw-r--r--resources/image.go61
1 files changed, 38 insertions, 23 deletions
diff --git a/resources/image.go b/resources/image.go
index e1a816942..7113284f7 100644
--- a/resources/image.go
+++ b/resources/image.go
@@ -16,18 +16,19 @@ package resources
import (
"fmt"
"image"
- "image/color"
"image/draw"
_ "image/gif"
_ "image/png"
"os"
"strings"
+ "github.com/gohugoio/hugo/resources/internal"
+
"github.com/gohugoio/hugo/resources/resource"
_errors "github.com/pkg/errors"
- "github.com/disintegration/imaging"
+ "github.com/disintegration/gift"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/resources/images"
@@ -82,16 +83,26 @@ func (i *imageResource) cloneWithUpdates(u *transformationUpdate) (baseResource,
// filter and returns the transformed image. If one of width or height is 0, the image aspect
// ratio is preserved.
func (i *imageResource) Resize(spec string) (resource.Image, error) {
- return i.doWithImageConfig("resize", spec, func(src image.Image, conf images.ImageConfig) (image.Image, error) {
- return i.Proc.Resize(src, conf)
+ conf, err := i.decodeImageConfig("resize", spec)
+ if err != nil {
+ return nil, err
+ }
+
+ return i.doWithImageConfig(conf, func(src image.Image) (image.Image, error) {
+ return i.Proc.ApplyFiltersFromConfig(src, conf)
})
}
// Fit scales down the image using the specified resample filter to fit the specified
// maximum width and height.
func (i *imageResource) Fit(spec string) (resource.Image, error) {
- return i.doWithImageConfig("fit", spec, func(src image.Image, conf images.ImageConfig) (image.Image, error) {
- return i.Proc.Fit(src, conf)
+ conf, err := i.decodeImageConfig("fit", spec)
+ if err != nil {
+ return nil, err
+ }
+
+ return i.doWithImageConfig(conf, func(src image.Image) (image.Image, error) {
+ return i.Proc.ApplyFiltersFromConfig(src, conf)
})
}
@@ -99,8 +110,22 @@ func (i *imageResource) Fit(spec string) (resource.Image, error) {
// crops the resized image to the specified dimensions using the given anchor point.
// Space delimited config: 200x300 TopLeft
func (i *imageResource) Fill(spec string) (resource.Image, error) {
- return i.doWithImageConfig("fill", spec, func(src image.Image, conf images.ImageConfig) (image.Image, error) {
- return i.Proc.Fill(src, conf)
+ conf, err := i.decodeImageConfig("fill", spec)
+ if err != nil {
+ return nil, err
+ }
+
+ return i.doWithImageConfig(conf, func(src image.Image) (image.Image, error) {
+ return i.Proc.ApplyFiltersFromConfig(src, conf)
+ })
+}
+
+func (i *imageResource) Filter(filters ...gift.Filter) (resource.Image, error) {
+ conf := i.Proc.GetDefaultImageConfig("filter")
+ conf.Key = internal.HashString(filters)
+
+ return i.doWithImageConfig(conf, func(src image.Image) (image.Image, error) {
+ return i.Proc.Filter(src, filters...)
})
}
@@ -118,19 +143,14 @@ const imageProcWorkers = 1
var imageProcSem = make(chan bool, imageProcWorkers)
-func (i *imageResource) doWithImageConfig(action, spec string, f func(src image.Image, conf images.ImageConfig) (image.Image, error)) (resource.Image, error) {
- conf, err := i.decodeImageConfig(action, spec)
- if err != nil {
- return nil, err
- }
-
+func (i *imageResource) doWithImageConfig(conf images.ImageConfig, f func(src image.Image) (image.Image, error)) (resource.Image, error) {
return i.getSpec().imageCache.getOrCreate(i, conf, func() (*imageResource, image.Image, error) {
imageProcSem <- true
defer func() {
<-imageProcSem
}()
- errOp := action
+ errOp := conf.Action
errPath := i.getSourceFilename()
src, err := i.decodeSource()
@@ -138,17 +158,12 @@ func (i *imageResource) doWithImageConfig(action, spec string, f func(src image.
return nil, nil, &os.PathError{Op: errOp, Path: errPath, Err: err}
}
- if conf.Rotate != 0 {
- // Rotate it before any scaling to get the dimensions correct.
- src = imaging.Rotate(src, float64(conf.Rotate), color.Transparent)
- }
-
- converted, err := f(src, conf)
+ converted, err := f(src)
if err != nil {
return nil, nil, &os.PathError{Op: errOp, Path: errPath, Err: err}
}
- if i.Format == imaging.PNG {
+ if i.Format == images.PNG {
// Apply the colour palette from the source
if paletted, ok := src.(*image.Paletted); ok {
tmp := image.NewPaletted(converted.Bounds(), paletted.Palette)
@@ -222,7 +237,7 @@ func (i *imageResource) relTargetPathFromConfig(conf images.ImageConfig) dirFile
// Do not change for no good reason.
const md5Threshold = 100
- key := conf.Key(i.Format)
+ key := conf.GetKey(i.Format)
// It is useful to have the key in clear text, but when nesting transforms, it
// can easily be too long to read, and maybe even too long