|
|
@@ -106,7 +106,7 @@ var gravityTypesRotationMap = map[int]map[GravityType]GravityType{
|
|
|
},
|
|
|
}
|
|
|
|
|
|
-var gravityTypesFlipMap = map[GravityType]GravityType{
|
|
|
+var gravityTypesFlipXMap = map[GravityType]GravityType{
|
|
|
GravityEast: GravityWest,
|
|
|
GravityWest: GravityEast,
|
|
|
GravityNorthWest: GravityNorthEast,
|
|
|
@@ -115,6 +115,15 @@ var gravityTypesFlipMap = map[GravityType]GravityType{
|
|
|
GravitySouthEast: GravitySouthWest,
|
|
|
}
|
|
|
|
|
|
+var gravityTypesFlipYMap = map[GravityType]GravityType{
|
|
|
+ GravityNorth: GravitySouth,
|
|
|
+ GravitySouth: GravityNorth,
|
|
|
+ GravityNorthWest: GravitySouthWest,
|
|
|
+ GravityNorthEast: GravitySouthEast,
|
|
|
+ GravitySouthWest: GravityNorthWest,
|
|
|
+ GravitySouthEast: GravityNorthEast,
|
|
|
+}
|
|
|
+
|
|
|
func (gt GravityType) String() string {
|
|
|
for k, v := range gravityTypes {
|
|
|
if v == gt {
|
|
|
@@ -138,11 +147,21 @@ type GravityOptions struct {
|
|
|
X, Y float64
|
|
|
}
|
|
|
|
|
|
-func (g *GravityOptions) RotateAndFlip(angle int, flip bool) {
|
|
|
+// RotateAndFlip rotates and flips the gravity options so that they correspond
|
|
|
+// to the image before rotation and flipping.
|
|
|
+//
|
|
|
+// By design, rotation and flipping are applied before cropping.
|
|
|
+// But for performance reasons, we do cropping before rotation and flipping.
|
|
|
+// So we need to adjust gravity options accordingly.
|
|
|
+// As a result, cropping with the adjusted gravity options
|
|
|
+// and then rotating/flipping the cropped image gives the same result
|
|
|
+// as rotating/flipping the image first and then cropping
|
|
|
+// with the original gravity options.
|
|
|
+func (g *GravityOptions) RotateAndFlip(angle int, flipX, flipY bool) {
|
|
|
angle %= 360
|
|
|
|
|
|
- if flip {
|
|
|
- if gt, ok := gravityTypesFlipMap[g.Type]; ok {
|
|
|
+ if flipX {
|
|
|
+ if gt, ok := gravityTypesFlipXMap[g.Type]; ok {
|
|
|
g.Type = gt
|
|
|
}
|
|
|
|
|
|
@@ -154,6 +173,19 @@ func (g *GravityOptions) RotateAndFlip(angle int, flip bool) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if flipY {
|
|
|
+ if gt, ok := gravityTypesFlipYMap[g.Type]; ok {
|
|
|
+ g.Type = gt
|
|
|
+ }
|
|
|
+
|
|
|
+ switch g.Type {
|
|
|
+ case GravityCenter, GravityEast, GravityWest:
|
|
|
+ g.Y = -g.Y
|
|
|
+ case GravityFocusPoint:
|
|
|
+ g.Y = 1.0 - g.Y
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if angle > 0 {
|
|
|
if rotMap := gravityTypesRotationMap[angle]; rotMap != nil {
|
|
|
if gt, ok := rotMap[g.Type]; ok {
|