1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-12-23 22:11:10 +02:00
Files
imgproxy/processing/gravity.go

125 lines
3.0 KiB
Go
Raw Permalink Normal View History

2025-09-23 20:16:36 +03:00
package processing
import (
"github.com/imgproxy/imgproxy/v3/options"
"github.com/imgproxy/imgproxy/v3/options/keys"
)
2025-09-25 19:48:53 +03:00
var gravityTypesRotationMap = map[int]map[GravityType]GravityType{
2025-09-23 20:16:36 +03:00
90: {
2025-09-25 19:48:53 +03:00
GravityNorth: GravityWest,
GravityEast: GravityNorth,
GravitySouth: GravityEast,
GravityWest: GravitySouth,
GravityNorthWest: GravitySouthWest,
GravityNorthEast: GravityNorthWest,
GravitySouthWest: GravitySouthEast,
GravitySouthEast: GravityNorthEast,
2025-09-23 20:16:36 +03:00
},
180: {
2025-09-25 19:48:53 +03:00
GravityNorth: GravitySouth,
GravityEast: GravityWest,
GravitySouth: GravityNorth,
GravityWest: GravityEast,
GravityNorthWest: GravitySouthEast,
GravityNorthEast: GravitySouthWest,
GravitySouthWest: GravityNorthEast,
GravitySouthEast: GravityNorthWest,
2025-09-23 20:16:36 +03:00
},
270: {
2025-09-25 19:48:53 +03:00
GravityNorth: GravityEast,
GravityEast: GravitySouth,
GravitySouth: GravityWest,
GravityWest: GravityNorth,
GravityNorthWest: GravityNorthEast,
GravityNorthEast: GravitySouthEast,
GravitySouthWest: GravityNorthWest,
GravitySouthEast: GravitySouthWest,
2025-09-23 20:16:36 +03:00
},
}
2025-09-25 19:48:53 +03:00
var gravityTypesFlipMap = map[GravityType]GravityType{
GravityEast: GravityWest,
GravityWest: GravityEast,
GravityNorthWest: GravityNorthEast,
GravityNorthEast: GravityNorthWest,
GravitySouthWest: GravitySouthEast,
GravitySouthEast: GravitySouthWest,
2025-09-23 20:16:36 +03:00
}
type GravityOptions struct {
2025-09-25 19:48:53 +03:00
Type GravityType
2025-09-23 20:16:36 +03:00
X, Y float64
}
// NewGravityOptions builds a new [GravityOptions] instance.
// It fills the [GravityOptions] struct with the options values under the given prefix.
// If the gravity type is not set in the options,
// it returns a [GravityOptions] with the provided default type.
2025-09-25 19:48:53 +03:00
func NewGravityOptions(o *options.Options, prefix string, defType GravityType) GravityOptions {
2025-09-23 20:16:36 +03:00
gr := GravityOptions{
Type: options.Get(o, prefix+keys.SuffixType, defType),
2025-09-23 20:16:36 +03:00
X: o.GetFloat(prefix+keys.SuffixXOffset, 0.0),
Y: o.GetFloat(prefix+keys.SuffixYOffset, 0.0),
}
return gr
}
func (g *GravityOptions) RotateAndFlip(angle int, flip bool) {
angle %= 360
if flip {
if gt, ok := gravityTypesFlipMap[g.Type]; ok {
g.Type = gt
}
switch g.Type {
2025-09-25 19:48:53 +03:00
case GravityCenter, GravityNorth, GravitySouth:
2025-09-23 20:16:36 +03:00
g.X = -g.X
2025-09-25 19:48:53 +03:00
case GravityFocusPoint:
2025-09-23 20:16:36 +03:00
g.X = 1.0 - g.X
}
}
if angle > 0 {
if rotMap := gravityTypesRotationMap[angle]; rotMap != nil {
if gt, ok := rotMap[g.Type]; ok {
g.Type = gt
}
switch angle {
case 90:
switch g.Type {
2025-09-25 19:48:53 +03:00
case GravityCenter, GravityEast, GravityWest:
2025-09-23 20:16:36 +03:00
g.X, g.Y = g.Y, -g.X
2025-09-25 19:48:53 +03:00
case GravityFocusPoint:
2025-09-23 20:16:36 +03:00
g.X, g.Y = g.Y, 1.0-g.X
default:
g.X, g.Y = g.Y, g.X
}
case 180:
switch g.Type {
2025-09-25 19:48:53 +03:00
case GravityCenter:
2025-09-23 20:16:36 +03:00
g.X, g.Y = -g.X, -g.Y
2025-09-25 19:48:53 +03:00
case GravityNorth, GravitySouth:
2025-09-23 20:16:36 +03:00
g.X = -g.X
2025-09-25 19:48:53 +03:00
case GravityEast, GravityWest:
2025-09-23 20:16:36 +03:00
g.Y = -g.Y
2025-09-25 19:48:53 +03:00
case GravityFocusPoint:
2025-09-23 20:16:36 +03:00
g.X, g.Y = 1.0-g.X, 1.0-g.Y
}
case 270:
switch g.Type {
2025-09-25 19:48:53 +03:00
case GravityCenter, GravityNorth, GravitySouth:
2025-09-23 20:16:36 +03:00
g.X, g.Y = -g.Y, g.X
2025-09-25 19:48:53 +03:00
case GravityFocusPoint:
2025-09-23 20:16:36 +03:00
g.X, g.Y = 1.0-g.Y, g.X
default:
g.X, g.Y = g.Y, g.X
}
}
}
}
}