mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-13 20:24:00 +02:00
committed by
Bjørn Erik Pedersen
parent
8af04745fb
commit
71fae99189
@@ -52,6 +52,14 @@ func (*Filters) Overlay(src ImageSource, x, y any) gift.Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mask creates a filter that applies a mask image to the source image.
|
||||||
|
func (*Filters) Mask(mask ImageSource) gift.Filter {
|
||||||
|
return filter{
|
||||||
|
Options: newFilterOpts(mask.Key()),
|
||||||
|
Filter: maskFilter{mask: mask},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Opacity creates a filter that changes the opacity of an image.
|
// Opacity creates a filter that changes the opacity of an image.
|
||||||
// The opacity parameter must be in range (0, 1).
|
// The opacity parameter must be in range (0, 1).
|
||||||
func (*Filters) Opacity(opacity any) gift.Filter {
|
func (*Filters) Opacity(opacity any) gift.Filter {
|
||||||
|
63
resources/images/mask.go
Normal file
63
resources/images/mask.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
|
||||||
|
"github.com/disintegration/gift"
|
||||||
|
)
|
||||||
|
|
||||||
|
// maskFilter applies a mask image to a base image.
|
||||||
|
type maskFilter struct {
|
||||||
|
mask ImageSource
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw applies the mask to the base image.
|
||||||
|
func (f maskFilter) Draw(dst draw.Image, baseImage image.Image, options *gift.Options) {
|
||||||
|
maskImage, err := f.mask.DecodeImage()
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to decode image: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the mask is the same size as the base image
|
||||||
|
baseBounds := baseImage.Bounds()
|
||||||
|
maskBounds := maskImage.Bounds()
|
||||||
|
|
||||||
|
// Resize mask to match base image size if necessary
|
||||||
|
if maskBounds.Dx() != baseBounds.Dx() || maskBounds.Dy() != baseBounds.Dy() {
|
||||||
|
g := gift.New(gift.Resize(baseBounds.Dx(), baseBounds.Dy(), gift.LanczosResampling))
|
||||||
|
resizedMask := image.NewRGBA(g.Bounds(maskImage.Bounds()))
|
||||||
|
g.Draw(resizedMask, maskImage)
|
||||||
|
maskImage = resizedMask
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use gift to convert the resized mask to grayscale
|
||||||
|
g := gift.New(gift.Grayscale())
|
||||||
|
grayscaleMask := image.NewGray(g.Bounds(maskImage.Bounds()))
|
||||||
|
g.Draw(grayscaleMask, maskImage)
|
||||||
|
|
||||||
|
// Convert grayscale mask to alpha mask
|
||||||
|
alphaMask := image.NewAlpha(baseBounds)
|
||||||
|
for y := baseBounds.Min.Y; y < baseBounds.Max.Y; y++ {
|
||||||
|
for x := baseBounds.Min.X; x < baseBounds.Max.X; x++ {
|
||||||
|
grayValue := grayscaleMask.GrayAt(x, y).Y
|
||||||
|
alphaMask.SetAlpha(x, y, color.Alpha{A: grayValue})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an RGBA output image
|
||||||
|
outputImage := image.NewRGBA(baseBounds)
|
||||||
|
|
||||||
|
// Apply the mask using draw.DrawMask
|
||||||
|
draw.DrawMask(outputImage, baseBounds, baseImage, image.Point{}, alphaMask, image.Point{}, draw.Over)
|
||||||
|
|
||||||
|
// Copy the result to the destination
|
||||||
|
gift.New().Draw(dst, outputImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds returns the bounds of the resulting image.
|
||||||
|
func (f maskFilter) Bounds(imgBounds image.Rectangle) image.Rectangle {
|
||||||
|
return image.Rect(0, 0, imgBounds.Dx(), imgBounds.Dy())
|
||||||
|
}
|
Reference in New Issue
Block a user