pipeline.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package processing
  2. import (
  3. "context"
  4. "github.com/imgproxy/imgproxy/v3/auximageprovider"
  5. "github.com/imgproxy/imgproxy/v3/imagedata"
  6. "github.com/imgproxy/imgproxy/v3/options"
  7. "github.com/imgproxy/imgproxy/v3/processing/pipeline"
  8. "github.com/imgproxy/imgproxy/v3/server"
  9. "github.com/imgproxy/imgproxy/v3/vips"
  10. )
  11. // NOTE: this will be called pipeline.Context in the separate package
  12. type Context struct {
  13. Ctx context.Context
  14. // Global processing configuration which could be used by individual steps
  15. Config *pipeline.Config
  16. // VIPS image
  17. Img *vips.Image
  18. // Processing options this pipeline runs with
  19. PO *options.ProcessingOptions
  20. // Source image data
  21. ImgData imagedata.ImageData
  22. // The watermark image provider, if any watermarking is to be done.
  23. WatermarkProvider auximageprovider.Provider
  24. SrcWidth int
  25. SrcHeight int
  26. Angle int
  27. Flip bool
  28. CropWidth int
  29. CropHeight int
  30. CropGravity options.GravityOptions
  31. WScale float64
  32. HScale float64
  33. DprScale float64
  34. // The base scale factor for vector images.
  35. // It is used to downscale the input vector image to the maximum allowed resolution
  36. VectorBaseScale float64
  37. // The width we aim to get.
  38. // Based on the requested width scaled according to processing options.
  39. // Can be 0 if width is not specified in the processing options.
  40. TargetWidth int
  41. // The height we aim to get.
  42. // Based on the requested height scaled according to processing options.
  43. // Can be 0 if height is not specified in the processing options.
  44. TargetHeight int
  45. // The width of the image after cropping, scaling and rotating
  46. ScaledWidth int
  47. // The height of the image after cropping, scaling and rotating
  48. ScaledHeight int
  49. // The width of the result crop according to the resizing type
  50. ResultCropWidth int
  51. // The height of the result crop according to the resizing type
  52. ResultCropHeight int
  53. // The width of the image extended to the requested aspect ratio.
  54. // Can be 0 if any of the dimensions is not specified in the processing options
  55. // or if the image already has the requested aspect ratio.
  56. ExtendAspectRatioWidth int
  57. // The width of the image extended to the requested aspect ratio.
  58. // Can be 0 if any of the dimensions is not specified in the processing options
  59. // or if the image already has the requested aspect ratio.
  60. ExtendAspectRatioHeight int
  61. }
  62. // NOTE: same, pipeline.Step, pipeline.Pipeline, pipeline.Runner
  63. type Step func(ctx *Context) error
  64. type Pipeline []Step
  65. // Runner is responsible for running a processing pipeline
  66. type Runner struct {
  67. config *pipeline.Config
  68. watermark auximageprovider.Provider
  69. }
  70. // New creates a new Runner instance with the given configuration and watermark provider
  71. func New(config *pipeline.Config, watermark auximageprovider.Provider) *Runner {
  72. return &Runner{
  73. config: config,
  74. watermark: watermark,
  75. }
  76. }
  77. // Run runs the given pipeline with the given parameters
  78. func (f *Runner) Run(
  79. p Pipeline,
  80. ctx context.Context,
  81. img *vips.Image,
  82. po *options.ProcessingOptions,
  83. imgdata imagedata.ImageData,
  84. ) error {
  85. pctx := f.newContext(ctx, img, po, imgdata)
  86. for _, step := range p {
  87. if err := step(&pctx); err != nil {
  88. return err
  89. }
  90. if err := server.CheckTimeout(ctx); err != nil {
  91. return err
  92. }
  93. }
  94. img.SetDouble("imgproxy-dpr-scale", pctx.DprScale)
  95. return nil
  96. }
  97. func (r *Runner) newContext(
  98. ctx context.Context,
  99. img *vips.Image,
  100. po *options.ProcessingOptions,
  101. imgdata imagedata.ImageData,
  102. ) Context {
  103. pctx := Context{
  104. Ctx: ctx,
  105. Config: r.config,
  106. Img: img,
  107. PO: po,
  108. ImgData: imgdata,
  109. WScale: 1.0,
  110. HScale: 1.0,
  111. DprScale: 1.0,
  112. VectorBaseScale: 1.0,
  113. CropGravity: po.Crop.Gravity,
  114. WatermarkProvider: r.watermark,
  115. }
  116. if pctx.CropGravity.Type == options.GravityUnknown {
  117. pctx.CropGravity = po.Gravity
  118. }
  119. return pctx
  120. }