1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-01-08 10:45:04 +02:00
imgproxy/options/gravity_options.go
2022-01-17 18:39:59 +06:00

159 lines
3.3 KiB
Go

package options
import (
"fmt"
)
type GravityType int
const (
GravityUnknown GravityType = iota
GravityCenter
GravityNorth
GravityEast
GravitySouth
GravityWest
GravityNorthWest
GravityNorthEast
GravitySouthWest
GravitySouthEast
GravitySmart
GravityFocusPoint
)
var gravityTypes = map[string]GravityType{
"ce": GravityCenter,
"no": GravityNorth,
"ea": GravityEast,
"so": GravitySouth,
"we": GravityWest,
"nowe": GravityNorthWest,
"noea": GravityNorthEast,
"sowe": GravitySouthWest,
"soea": GravitySouthEast,
"sm": GravitySmart,
"fp": GravityFocusPoint,
}
var gravityTypesRotationMap = map[int]map[GravityType]GravityType{
90: {
GravityNorth: GravityWest,
GravityEast: GravityNorth,
GravitySouth: GravityEast,
GravityWest: GravitySouth,
GravityNorthWest: GravitySouthWest,
GravityNorthEast: GravityNorthWest,
GravitySouthWest: GravitySouthEast,
GravitySouthEast: GravityNorthEast,
},
180: {
GravityNorth: GravitySouth,
GravityEast: GravityWest,
GravitySouth: GravityNorth,
GravityWest: GravityEast,
GravityNorthWest: GravitySouthEast,
GravityNorthEast: GravitySouthWest,
GravitySouthWest: GravityNorthEast,
GravitySouthEast: GravityNorthWest,
},
270: {
GravityNorth: GravityEast,
GravityEast: GravitySouth,
GravitySouth: GravityWest,
GravityWest: GravityNorth,
GravityNorthWest: GravityNorthEast,
GravityNorthEast: GravitySouthEast,
GravitySouthWest: GravityNorthWest,
GravitySouthEast: GravitySouthWest,
},
}
var gravityTypesFlipMap = map[GravityType]GravityType{
GravityEast: GravityWest,
GravityWest: GravityEast,
GravityNorthWest: GravityNorthEast,
GravityNorthEast: GravityNorthWest,
GravitySouthWest: GravitySouthEast,
GravitySouthEast: GravitySouthWest,
}
func (gt GravityType) String() string {
for k, v := range gravityTypes {
if v == gt {
return k
}
}
return ""
}
func (gt GravityType) MarshalJSON() ([]byte, error) {
for k, v := range gravityTypes {
if v == gt {
return []byte(fmt.Sprintf("%q", k)), nil
}
}
return []byte("null"), nil
}
type GravityOptions struct {
Type GravityType
X, Y float64
}
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 {
case GravityCenter, GravityNorth, GravitySouth:
g.X = -g.X
case GravityFocusPoint:
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 {
case GravityCenter, GravityEast, GravityWest:
g.X, g.Y = g.Y, -g.X
case GravityFocusPoint:
g.X, g.Y = g.Y, 1.0-g.X
default:
g.X, g.Y = g.Y, g.X
}
case 180:
switch g.Type {
case GravityCenter:
g.X, g.Y = -g.X, -g.Y
case GravityNorth, GravitySouth:
g.X = -g.X
case GravityEast, GravityWest:
g.Y = -g.Y
case GravityFocusPoint:
g.X, g.Y = 1.0-g.X, 1.0-g.Y
}
case 270:
switch g.Type {
case GravityCenter, GravityNorth, GravitySouth:
g.X, g.Y = -g.Y, g.X
case GravityFocusPoint:
g.X, g.Y = 1.0-g.Y, g.X
default:
g.X, g.Y = g.Y, g.X
}
}
}
}
}