1
0

options.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package processing
  2. import (
  3. "slices"
  4. "github.com/imgproxy/imgproxy/v3/imagetype"
  5. "github.com/imgproxy/imgproxy/v3/options"
  6. "github.com/imgproxy/imgproxy/v3/options/keys"
  7. "github.com/imgproxy/imgproxy/v3/vips/color"
  8. )
  9. // ProcessingOptions is a thin wrapper around options.Options that provides
  10. // helpers for image processing options.
  11. type ProcessingOptions struct {
  12. *options.Options
  13. // Config that contains default values for some options.
  14. config *Config
  15. }
  16. func (p *Processor) NewProcessingOptions(o *options.Options) ProcessingOptions {
  17. return ProcessingOptions{
  18. Options: o,
  19. config: p.config,
  20. }
  21. }
  22. func (po ProcessingOptions) Width() int {
  23. return po.GetInt(keys.Width, 0)
  24. }
  25. func (po ProcessingOptions) Height() int {
  26. return po.GetInt(keys.Height, 0)
  27. }
  28. func (po ProcessingOptions) MinWidth() int {
  29. return po.GetInt(keys.MinWidth, 0)
  30. }
  31. func (po ProcessingOptions) MinHeight() int {
  32. return po.GetInt(keys.MinHeight, 0)
  33. }
  34. func (po ProcessingOptions) ResizingType() ResizeType {
  35. return options.Get(po.Options, keys.ResizingType, ResizeFit)
  36. }
  37. func (po ProcessingOptions) ZoomWidth() float64 {
  38. return po.GetFloat(keys.ZoomWidth, 1.0)
  39. }
  40. func (po ProcessingOptions) ZoomHeight() float64 {
  41. return po.GetFloat(keys.ZoomHeight, 1.0)
  42. }
  43. func (po ProcessingOptions) DPR() float64 {
  44. return po.GetFloat(keys.Dpr, 1.0)
  45. }
  46. func (po ProcessingOptions) EnforceThumbnail() bool {
  47. return po.Main().GetBool(keys.EnforceThumbnail, po.config.EnforceThumbnail)
  48. }
  49. func (po ProcessingOptions) Enlarge() bool {
  50. return po.GetBool(keys.Enlarge, false)
  51. }
  52. func (po ProcessingOptions) Gravity() GravityOptions {
  53. return NewGravityOptions(po.Options, keys.Gravity, GravityCenter)
  54. }
  55. func (po ProcessingOptions) ExtendEnabled() bool {
  56. return po.GetBool(keys.ExtendEnabled, false)
  57. }
  58. func (po ProcessingOptions) ExtendGravity() GravityOptions {
  59. return NewGravityOptions(po.Options, keys.ExtendGravity, GravityCenter)
  60. }
  61. func (po ProcessingOptions) ExtendAspectRatioEnabled() bool {
  62. return po.GetBool(keys.ExtendAspectRatioEnabled, false)
  63. }
  64. func (po ProcessingOptions) ExtendAspectRatioGravity() GravityOptions {
  65. return NewGravityOptions(po.Options, keys.ExtendAspectRatioGravity, GravityCenter)
  66. }
  67. func (po ProcessingOptions) Rotate() int {
  68. return po.GetInt(keys.Rotate, 0)
  69. }
  70. func (po ProcessingOptions) AutoRotate() bool {
  71. return po.GetBool(keys.AutoRotate, po.config.AutoRotate)
  72. }
  73. func (po ProcessingOptions) CropWidth() float64 {
  74. return po.GetFloat(keys.CropWidth, 0.0)
  75. }
  76. func (po ProcessingOptions) CropHeight() float64 {
  77. return po.GetFloat(keys.CropHeight, 0.0)
  78. }
  79. func (po ProcessingOptions) CropGravity() GravityOptions {
  80. return NewGravityOptions(po.Options, keys.CropGravity, GravityUnknown)
  81. }
  82. func (po ProcessingOptions) Format() imagetype.Type {
  83. return options.Get(po.Main(), keys.Format, imagetype.Unknown)
  84. }
  85. func (po ProcessingOptions) SetFormat(format imagetype.Type) {
  86. po.Set(keys.Format, format)
  87. }
  88. func (po ProcessingOptions) ShouldSkipFormatProcessing(inFormat imagetype.Type) bool {
  89. return slices.Contains(po.config.SkipProcessingFormats, inFormat) ||
  90. options.SliceContains(po.Main(), keys.SkipProcessing, inFormat)
  91. }
  92. func (po ProcessingOptions) ShouldFlatten() bool {
  93. return po.Has(keys.Background)
  94. }
  95. func (po ProcessingOptions) Background() color.RGB {
  96. return options.Get(po.Options, keys.Background, color.RGB{R: 255, G: 255, B: 255})
  97. }
  98. func (po ProcessingOptions) PaddingEnabled() bool {
  99. return po.PaddingTop() != 0 ||
  100. po.PaddingRight() != 0 ||
  101. po.PaddingBottom() != 0 ||
  102. po.PaddingLeft() != 0
  103. }
  104. func (po ProcessingOptions) PaddingTop() int {
  105. return po.GetInt(keys.PaddingTop, 0)
  106. }
  107. func (po ProcessingOptions) PaddingRight() int {
  108. return po.GetInt(keys.PaddingRight, 0)
  109. }
  110. func (po ProcessingOptions) PaddingBottom() int {
  111. return po.GetInt(keys.PaddingBottom, 0)
  112. }
  113. func (po ProcessingOptions) PaddingLeft() int {
  114. return po.GetInt(keys.PaddingLeft, 0)
  115. }
  116. func (po ProcessingOptions) Blur() float64 {
  117. return po.GetFloat(keys.Blur, 0.0)
  118. }
  119. func (po ProcessingOptions) Sharpen() float64 {
  120. return po.GetFloat(keys.Sharpen, 0.0)
  121. }
  122. func (po ProcessingOptions) Pixelate() int {
  123. return po.GetInt(keys.Pixelate, 1)
  124. }
  125. func (po ProcessingOptions) PreferWebP() bool {
  126. return po.GetBool(keys.PreferWebP, false)
  127. }
  128. func (po ProcessingOptions) PreferAvif() bool {
  129. return po.GetBool(keys.PreferAvif, false)
  130. }
  131. func (po ProcessingOptions) PreferJxl() bool {
  132. return po.GetBool(keys.PreferJxl, false)
  133. }
  134. func (po ProcessingOptions) EnforceWebP() bool {
  135. return po.GetBool(keys.EnforceWebP, false)
  136. }
  137. func (po ProcessingOptions) EnforceAvif() bool {
  138. return po.GetBool(keys.EnforceAvif, false)
  139. }
  140. func (po ProcessingOptions) EnforceJxl() bool {
  141. return po.GetBool(keys.EnforceJxl, false)
  142. }
  143. func (po ProcessingOptions) TrimEnabled() bool {
  144. return po.Has(keys.TrimThreshold)
  145. }
  146. func (po ProcessingOptions) DisableTrim() {
  147. po.Delete(keys.TrimThreshold)
  148. }
  149. func (po ProcessingOptions) TrimThreshold() float64 {
  150. return po.GetFloat(keys.TrimThreshold, 10.0)
  151. }
  152. func (po ProcessingOptions) TrimSmart() bool {
  153. return !po.Has(keys.TrimColor)
  154. }
  155. func (po ProcessingOptions) TrimColor() color.RGB {
  156. return options.Get(po.Options, keys.TrimColor, color.RGB{})
  157. }
  158. func (po ProcessingOptions) TrimEqualHor() bool {
  159. return po.GetBool(keys.TrimEqualHor, false)
  160. }
  161. func (po ProcessingOptions) TrimEqualVer() bool {
  162. return po.GetBool(keys.TrimEqualVer, false)
  163. }
  164. func (po ProcessingOptions) WatermarkOpacity() float64 {
  165. return po.GetFloat(keys.WatermarkOpacity, 0.0)
  166. }
  167. func (po ProcessingOptions) SetWatermarkOpacity(opacity float64) {
  168. po.Set(keys.WatermarkOpacity, opacity)
  169. }
  170. func (po ProcessingOptions) DeleteWatermarkOpacity() {
  171. po.Delete(keys.WatermarkOpacity)
  172. }
  173. func (po ProcessingOptions) WatermarkPosition() GravityType {
  174. return options.Get(po.Options, keys.WatermarkPosition, GravityCenter)
  175. }
  176. func (po ProcessingOptions) WatermarkXOffset() float64 {
  177. return po.GetFloat(keys.WatermarkXOffset, 0.0)
  178. }
  179. func (po ProcessingOptions) WatermarkYOffset() float64 {
  180. return po.GetFloat(keys.WatermarkYOffset, 0.0)
  181. }
  182. func (po ProcessingOptions) WatermarkScale() float64 {
  183. return po.GetFloat(keys.WatermarkScale, 0.0)
  184. }
  185. // Quality retrieves the quality setting for a given image format.
  186. // It first checks for a general quality setting, then for a format-specific setting,
  187. // and finally falls back to the configured default quality.
  188. func (po ProcessingOptions) Quality(format imagetype.Type) int {
  189. // First, check if quality is explicitly set in options.
  190. if q := po.Main().GetInt(keys.Quality, 0); q > 0 {
  191. return q
  192. }
  193. // Then, check if format-specific quality is set in options.
  194. if q := po.Main().GetInt(keys.FormatQuality(format), 0); q > 0 {
  195. return q
  196. }
  197. // Then, check if format-specific quality is set in config.
  198. if q := po.config.FormatQuality[format]; q > 0 {
  199. return q
  200. }
  201. // Finally, return the general quality setting from config.
  202. return po.config.Quality
  203. }
  204. func (po ProcessingOptions) MaxBytes() int {
  205. return po.Main().GetInt(keys.MaxBytes, 0)
  206. }
  207. func (po ProcessingOptions) StripMetadata() bool {
  208. return po.Main().GetBool(keys.StripMetadata, po.config.StripMetadata)
  209. }
  210. func (po ProcessingOptions) KeepCopyright() bool {
  211. return po.Main().GetBool(keys.KeepCopyright, po.config.KeepCopyright)
  212. }
  213. func (po ProcessingOptions) StripColorProfile() bool {
  214. return po.Main().GetBool(keys.StripColorProfile, po.config.StripColorProfile)
  215. }