gravity_options.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package options
  2. import (
  3. "fmt"
  4. )
  5. type GravityType int
  6. const (
  7. GravityUnknown GravityType = iota
  8. GravityCenter
  9. GravityNorth
  10. GravityEast
  11. GravitySouth
  12. GravityWest
  13. GravityNorthWest
  14. GravityNorthEast
  15. GravitySouthWest
  16. GravitySouthEast
  17. GravitySmart
  18. GravityFocusPoint
  19. // Watermark gravity types
  20. GravityReplicate
  21. )
  22. var gravityTypes = map[string]GravityType{
  23. "ce": GravityCenter,
  24. "no": GravityNorth,
  25. "ea": GravityEast,
  26. "so": GravitySouth,
  27. "we": GravityWest,
  28. "nowe": GravityNorthWest,
  29. "noea": GravityNorthEast,
  30. "sowe": GravitySouthWest,
  31. "soea": GravitySouthEast,
  32. "sm": GravitySmart,
  33. "fp": GravityFocusPoint,
  34. "re": GravityReplicate,
  35. }
  36. var gravityTypesRotationMap = map[int]map[GravityType]GravityType{
  37. 90: {
  38. GravityNorth: GravityWest,
  39. GravityEast: GravityNorth,
  40. GravitySouth: GravityEast,
  41. GravityWest: GravitySouth,
  42. GravityNorthWest: GravitySouthWest,
  43. GravityNorthEast: GravityNorthWest,
  44. GravitySouthWest: GravitySouthEast,
  45. GravitySouthEast: GravityNorthEast,
  46. },
  47. 180: {
  48. GravityNorth: GravitySouth,
  49. GravityEast: GravityWest,
  50. GravitySouth: GravityNorth,
  51. GravityWest: GravityEast,
  52. GravityNorthWest: GravitySouthEast,
  53. GravityNorthEast: GravitySouthWest,
  54. GravitySouthWest: GravityNorthEast,
  55. GravitySouthEast: GravityNorthWest,
  56. },
  57. 270: {
  58. GravityNorth: GravityEast,
  59. GravityEast: GravitySouth,
  60. GravitySouth: GravityWest,
  61. GravityWest: GravityNorth,
  62. GravityNorthWest: GravityNorthEast,
  63. GravityNorthEast: GravitySouthEast,
  64. GravitySouthWest: GravityNorthWest,
  65. GravitySouthEast: GravitySouthWest,
  66. },
  67. }
  68. var gravityTypesFlipMap = map[GravityType]GravityType{
  69. GravityEast: GravityWest,
  70. GravityWest: GravityEast,
  71. GravityNorthWest: GravityNorthEast,
  72. GravityNorthEast: GravityNorthWest,
  73. GravitySouthWest: GravitySouthEast,
  74. GravitySouthEast: GravitySouthWest,
  75. }
  76. func (gt GravityType) String() string {
  77. for k, v := range gravityTypes {
  78. if v == gt {
  79. return k
  80. }
  81. }
  82. return ""
  83. }
  84. func (gt GravityType) MarshalJSON() ([]byte, error) {
  85. for k, v := range gravityTypes {
  86. if v == gt {
  87. return []byte(fmt.Sprintf("%q", k)), nil
  88. }
  89. }
  90. return []byte("null"), nil
  91. }
  92. func (gt GravityType) OkForCrop() bool {
  93. return gt != GravityUnknown && gt != GravityReplicate
  94. }
  95. func (gt GravityType) OkForExtend() bool {
  96. return gt.OkForCrop() && gt != GravitySmart
  97. }
  98. func (gt GravityType) OkForWatermark() bool {
  99. return gt == GravityReplicate ||
  100. (gt.OkForExtend() && gt != GravityFocusPoint)
  101. }
  102. type GravityOptions struct {
  103. Type GravityType
  104. X, Y float64
  105. }
  106. func (g *GravityOptions) RotateAndFlip(angle int, flip bool) {
  107. angle %= 360
  108. if flip {
  109. if gt, ok := gravityTypesFlipMap[g.Type]; ok {
  110. g.Type = gt
  111. }
  112. switch g.Type {
  113. case GravityCenter, GravityNorth, GravitySouth:
  114. g.X = -g.X
  115. case GravityFocusPoint:
  116. g.X = 1.0 - g.X
  117. }
  118. }
  119. if angle > 0 {
  120. if rotMap := gravityTypesRotationMap[angle]; rotMap != nil {
  121. if gt, ok := rotMap[g.Type]; ok {
  122. g.Type = gt
  123. }
  124. switch angle {
  125. case 90:
  126. switch g.Type {
  127. case GravityCenter, GravityEast, GravityWest:
  128. g.X, g.Y = g.Y, -g.X
  129. case GravityFocusPoint:
  130. g.X, g.Y = g.Y, 1.0-g.X
  131. default:
  132. g.X, g.Y = g.Y, g.X
  133. }
  134. case 180:
  135. switch g.Type {
  136. case GravityCenter:
  137. g.X, g.Y = -g.X, -g.Y
  138. case GravityNorth, GravitySouth:
  139. g.X = -g.X
  140. case GravityEast, GravityWest:
  141. g.Y = -g.Y
  142. case GravityFocusPoint:
  143. g.X, g.Y = 1.0-g.X, 1.0-g.Y
  144. }
  145. case 270:
  146. switch g.Type {
  147. case GravityCenter, GravityNorth, GravitySouth:
  148. g.X, g.Y = -g.Y, g.X
  149. case GravityFocusPoint:
  150. g.X, g.Y = 1.0-g.Y, g.X
  151. default:
  152. g.X, g.Y = g.Y, g.X
  153. }
  154. }
  155. }
  156. }
  157. }