gravity.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package processing
  2. import (
  3. "github.com/imgproxy/imgproxy/v3/options"
  4. "github.com/imgproxy/imgproxy/v3/options/keys"
  5. )
  6. var gravityTypesRotationMap = map[int]map[options.GravityType]options.GravityType{
  7. 90: {
  8. options.GravityNorth: options.GravityWest,
  9. options.GravityEast: options.GravityNorth,
  10. options.GravitySouth: options.GravityEast,
  11. options.GravityWest: options.GravitySouth,
  12. options.GravityNorthWest: options.GravitySouthWest,
  13. options.GravityNorthEast: options.GravityNorthWest,
  14. options.GravitySouthWest: options.GravitySouthEast,
  15. options.GravitySouthEast: options.GravityNorthEast,
  16. },
  17. 180: {
  18. options.GravityNorth: options.GravitySouth,
  19. options.GravityEast: options.GravityWest,
  20. options.GravitySouth: options.GravityNorth,
  21. options.GravityWest: options.GravityEast,
  22. options.GravityNorthWest: options.GravitySouthEast,
  23. options.GravityNorthEast: options.GravitySouthWest,
  24. options.GravitySouthWest: options.GravityNorthEast,
  25. options.GravitySouthEast: options.GravityNorthWest,
  26. },
  27. 270: {
  28. options.GravityNorth: options.GravityEast,
  29. options.GravityEast: options.GravitySouth,
  30. options.GravitySouth: options.GravityWest,
  31. options.GravityWest: options.GravityNorth,
  32. options.GravityNorthWest: options.GravityNorthEast,
  33. options.GravityNorthEast: options.GravitySouthEast,
  34. options.GravitySouthWest: options.GravityNorthWest,
  35. options.GravitySouthEast: options.GravitySouthWest,
  36. },
  37. }
  38. var gravityTypesFlipMap = map[options.GravityType]options.GravityType{
  39. options.GravityEast: options.GravityWest,
  40. options.GravityWest: options.GravityEast,
  41. options.GravityNorthWest: options.GravityNorthEast,
  42. options.GravityNorthEast: options.GravityNorthWest,
  43. options.GravitySouthWest: options.GravitySouthEast,
  44. options.GravitySouthEast: options.GravitySouthWest,
  45. }
  46. type GravityOptions struct {
  47. Type options.GravityType
  48. X, Y float64
  49. }
  50. // NewGravityOptions builds a new [GravityOptions] instance.
  51. // It fills the [GravityOptions] struct with the options values under the given prefix.
  52. // If the gravity type is not set in the options,
  53. // it returns a [GravityOptions] with the provided default type.
  54. func NewGravityOptions(o *options.Options, prefix string, defType options.GravityType) GravityOptions {
  55. gr := GravityOptions{
  56. Type: options.Get(o, prefix+keys.SuffixType, defType),
  57. X: o.GetFloat(prefix+keys.SuffixXOffset, 0.0),
  58. Y: o.GetFloat(prefix+keys.SuffixYOffset, 0.0),
  59. }
  60. return gr
  61. }
  62. func (g *GravityOptions) RotateAndFlip(angle int, flip bool) {
  63. angle %= 360
  64. if flip {
  65. if gt, ok := gravityTypesFlipMap[g.Type]; ok {
  66. g.Type = gt
  67. }
  68. switch g.Type {
  69. case options.GravityCenter, options.GravityNorth, options.GravitySouth:
  70. g.X = -g.X
  71. case options.GravityFocusPoint:
  72. g.X = 1.0 - g.X
  73. }
  74. }
  75. if angle > 0 {
  76. if rotMap := gravityTypesRotationMap[angle]; rotMap != nil {
  77. if gt, ok := rotMap[g.Type]; ok {
  78. g.Type = gt
  79. }
  80. switch angle {
  81. case 90:
  82. switch g.Type {
  83. case options.GravityCenter, options.GravityEast, options.GravityWest:
  84. g.X, g.Y = g.Y, -g.X
  85. case options.GravityFocusPoint:
  86. g.X, g.Y = g.Y, 1.0-g.X
  87. default:
  88. g.X, g.Y = g.Y, g.X
  89. }
  90. case 180:
  91. switch g.Type {
  92. case options.GravityCenter:
  93. g.X, g.Y = -g.X, -g.Y
  94. case options.GravityNorth, options.GravitySouth:
  95. g.X = -g.X
  96. case options.GravityEast, options.GravityWest:
  97. g.Y = -g.Y
  98. case options.GravityFocusPoint:
  99. g.X, g.Y = 1.0-g.X, 1.0-g.Y
  100. }
  101. case 270:
  102. switch g.Type {
  103. case options.GravityCenter, options.GravityNorth, options.GravitySouth:
  104. g.X, g.Y = -g.Y, g.X
  105. case options.GravityFocusPoint:
  106. g.X, g.Y = 1.0-g.Y, g.X
  107. default:
  108. g.X, g.Y = g.Y, g.X
  109. }
  110. }
  111. }
  112. }
  113. }