watermark.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package processing
  2. import (
  3. "context"
  4. "github.com/imgproxy/imgproxy/v3/config"
  5. "github.com/imgproxy/imgproxy/v3/imagedata"
  6. "github.com/imgproxy/imgproxy/v3/imath"
  7. "github.com/imgproxy/imgproxy/v3/options"
  8. "github.com/imgproxy/imgproxy/v3/vips"
  9. )
  10. var watermarkPipeline = pipeline{
  11. prepare,
  12. scaleOnLoad,
  13. importColorProfile,
  14. scale,
  15. rotateAndFlip,
  16. exportColorProfile,
  17. finalize,
  18. }
  19. func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options.WatermarkOptions, imgWidth, imgHeight int) error {
  20. if err := wm.Load(wmData, 1, 1.0, 1); err != nil {
  21. return err
  22. }
  23. po := options.NewProcessingOptions()
  24. po.ResizingType = options.ResizeFit
  25. po.Dpr = 1
  26. po.Enlarge = true
  27. po.Format = wmData.Type
  28. if opts.Scale > 0 {
  29. po.Width = imath.Max(imath.Scale(imgWidth, opts.Scale), 1)
  30. po.Height = imath.Max(imath.Scale(imgHeight, opts.Scale), 1)
  31. }
  32. if err := watermarkPipeline.Run(context.Background(), wm, po, wmData); err != nil {
  33. return err
  34. }
  35. if opts.Replicate {
  36. return wm.Replicate(imgWidth, imgHeight)
  37. }
  38. left, top := calcPosition(imgWidth, imgHeight, wm.Width(), wm.Height(), &opts.Gravity, true)
  39. return wm.Embed(imgWidth, imgHeight, left, top)
  40. }
  41. func applyWatermark(img *vips.Image, wmData *imagedata.ImageData, opts *options.WatermarkOptions, framesCount int) error {
  42. if err := img.RgbColourspace(); err != nil {
  43. return err
  44. }
  45. if err := img.CopyMemory(); err != nil {
  46. return err
  47. }
  48. wm := new(vips.Image)
  49. defer wm.Clear()
  50. width := img.Width()
  51. height := img.Height()
  52. if err := prepareWatermark(wm, wmData, opts, width, height/framesCount); err != nil {
  53. return err
  54. }
  55. if framesCount > 1 {
  56. if err := wm.Replicate(width, height); err != nil {
  57. return err
  58. }
  59. }
  60. opacity := opts.Opacity * config.WatermarkOpacity
  61. return img.ApplyWatermark(wm, opacity)
  62. }
  63. func watermark(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
  64. if !po.Watermark.Enabled || imagedata.Watermark == nil {
  65. return nil
  66. }
  67. return applyWatermark(img, imagedata.Watermark, &po.Watermark, 1)
  68. }