pipeline.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package processing
  2. import (
  3. "context"
  4. "github.com/imgproxy/imgproxy/v3/imagedata"
  5. "github.com/imgproxy/imgproxy/v3/options"
  6. "github.com/imgproxy/imgproxy/v3/security"
  7. "github.com/imgproxy/imgproxy/v3/server"
  8. "github.com/imgproxy/imgproxy/v3/vips"
  9. )
  10. type Context struct {
  11. // The context to check for timeouts and cancellations
  12. Ctx context.Context
  13. // Current image being processed
  14. Img *vips.Image
  15. // Processing options this pipeline runs with
  16. PO ProcessingOptions
  17. // Security options this pipeline runs with
  18. SecOps security.Options
  19. // Original image data
  20. ImgData imagedata.ImageData
  21. SrcWidth int
  22. SrcHeight int
  23. Angle int
  24. Flip bool
  25. CropWidth int
  26. CropHeight int
  27. CropGravity GravityOptions
  28. WScale float64
  29. HScale float64
  30. DprScale float64
  31. // The base scale factor for vector images.
  32. // It is used to downscale the input vector image to the maximum allowed resolution
  33. VectorBaseScale float64
  34. // The width we aim to get.
  35. // Based on the requested width scaled according to processing options.
  36. // Can be 0 if width is not specified in the processing options.
  37. TargetWidth int
  38. // The height we aim to get.
  39. // Based on the requested height scaled according to processing options.
  40. // Can be 0 if height is not specified in the processing options.
  41. TargetHeight int
  42. // The width of the image after cropping, scaling and rotating
  43. ScaledWidth int
  44. // The height of the image after cropping, scaling and rotating
  45. ScaledHeight int
  46. // The width of the result crop according to the resizing type
  47. ResultCropWidth int
  48. // The height of the result crop according to the resizing type
  49. ResultCropHeight int
  50. // The width of the image extended to the requested aspect ratio.
  51. // Can be 0 if any of the dimensions is not specified in the processing options
  52. // or if the image already has the requested aspect ratio.
  53. ExtendAspectRatioWidth int
  54. // The width of the image extended to the requested aspect ratio.
  55. // Can be 0 if any of the dimensions is not specified in the processing options
  56. // or if the image already has the requested aspect ratio.
  57. ExtendAspectRatioHeight int
  58. }
  59. type Step func(c *Context) error
  60. type Pipeline []Step
  61. // Run runs the given pipeline with the given parameters
  62. func (p Pipeline) Run(
  63. ctx context.Context,
  64. img *vips.Image,
  65. po ProcessingOptions,
  66. secops security.Options,
  67. imgdata imagedata.ImageData,
  68. ) error {
  69. pctx := p.newContext(ctx, img, po, secops, imgdata)
  70. pctx.CalcParams()
  71. for _, step := range p {
  72. if err := step(&pctx); err != nil {
  73. return err
  74. }
  75. if err := server.CheckTimeout(ctx); err != nil {
  76. return err
  77. }
  78. }
  79. img.SetDouble("imgproxy-dpr-scale", pctx.DprScale)
  80. return nil
  81. }
  82. func (p Pipeline) newContext(
  83. ctx context.Context,
  84. img *vips.Image,
  85. po ProcessingOptions,
  86. secops security.Options,
  87. imgdata imagedata.ImageData,
  88. ) Context {
  89. pctx := Context{
  90. Ctx: ctx,
  91. Img: img,
  92. PO: po,
  93. SecOps: secops,
  94. ImgData: imgdata,
  95. WScale: 1.0,
  96. HScale: 1.0,
  97. DprScale: 1.0,
  98. VectorBaseScale: 1.0,
  99. CropGravity: po.CropGravity(),
  100. }
  101. // If crop gravity is not set, use the general gravity option
  102. if pctx.CropGravity.Type == options.GravityUnknown {
  103. pctx.CropGravity = po.Gravity()
  104. }
  105. return pctx
  106. }