io.Closer
}
+// ReadSeekCloserProvider provides a ReadSeekCloser.
+type ReadSeekCloserProvider interface {
+ ReadSeekCloser() (ReadSeekCloser, error)
+}
+
// ReadSeekerNoOpCloser implements ReadSeekCloser by doing nothing in Close.
// TODO(bep) rename this and similar to ReadSeekerNopCloser, naming used in stdlib, which kind of makes sense.
type ReadSeekerNoOpCloser struct {
### Text
+{{< new-in "0.90.0" >}}
+
Using the `Text` filter, you can add text to an image.
{{% funcsig %}}
The following example will add the text `Hugo rocks!` to the image with the specified color, size and position.
-```
+```go-html-template
{{ $img := resources.Get "/images/background.png"}}
{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict
"color" "#ffffff"
))}}
```
+You can load a custom font if needed. Load the font as a Hugo `Resource` and set it as an option:
+
+```go-html-template
+
+{{ $font := resources.Get "https://github.com/google/fonts/raw/main/apache/roboto/static/Roboto-Black.ttf" }}
+{{ $img := resources.Get "/images/background.png"}}
+{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict
+ "font" $font
+))}}
+```
+
+
### Brightness
{{% funcsig %}}
c := qt.New(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
devMode := false
testImages := []string{"sunset.jpg", "gohugoio8.png", "gohugoio24.png"}
package images
import (
+ "fmt"
+
+ "github.com/gohugoio/hugo/common/hugio"
"github.com/gohugoio/hugo/common/maps"
+ "github.com/gohugoio/hugo/resources/resource"
"github.com/disintegration/gift"
"github.com/spf13/cast"
tf.y = cast.ToInt(v)
case "linespacing":
tf.linespacing = cast.ToInt(v)
+ case "font":
+ fontSource, ok1 := v.(hugio.ReadSeekCloserProvider)
+ identifier, ok2 := v.(resource.Identifier)
+
+ if !(ok1 && ok2) {
+ panic(fmt.Sprintf("invalid text font source: %T", v))
+ }
+
+ tf.fontSource = fontSource
+
+ // The input value isn't hashable and will not make a stable key.
+ // Replace it with a string in the map used as basis for the
+ // hash string.
+ opt["font"] = identifier.Key()
+
}
}
}
import (
"image"
"image/draw"
+ "io"
"strings"
"github.com/disintegration/gift"
+ "github.com/gohugoio/hugo/common/hugio"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
x, y int
size float64
linespacing int
+ fontSource hugio.ReadSeekCloserProvider
}
func (f textFilter) Draw(dst draw.Image, src image.Image, options *gift.Options) {
// Load and parse font
ttf := goregular.TTF
+ if f.fontSource != nil {
+ rs, err := f.fontSource.ReadSeekCloser()
+ if err != nil {
+ panic(err)
+ }
+ defer rs.Close()
+ ttf, err = io.ReadAll(rs)
+ if err != nil {
+ panic(err)
+ }
+ }
otf, err := opentype.Parse(ttf)
if err != nil {
panic(err)
// ReadSeekCloserResource is a Resource that supports loading its content.
type ReadSeekCloserResource interface {
MediaType() media.Type
- ReadSeekCloserProvider
-}
-
-type ReadSeekCloserProvider interface {
- ReadSeekCloser() (hugio.ReadSeekCloser, error)
+ hugio.ReadSeekCloserProvider
}
// LengthProvider is a Resource that provides a length