fix_size.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package processing
  2. import (
  3. "math"
  4. "github.com/imgproxy/imgproxy/v3/imagetype"
  5. "github.com/imgproxy/imgproxy/v3/vips"
  6. log "github.com/sirupsen/logrus"
  7. )
  8. const (
  9. // https://chromium.googlesource.com/webm/libwebp/+/refs/heads/master/src/webp/encode.h#529
  10. webpMaxDimension = 16383.0
  11. heifMaxDimension = 16384.0
  12. gifMaxDimension = 65535.0
  13. icoMaxDimension = 256.0
  14. )
  15. func fixWebpSize(img *vips.Image) error {
  16. webpLimitShrink := float64(max(img.Width(), img.Height())) / webpMaxDimension
  17. if webpLimitShrink <= 1.0 {
  18. return nil
  19. }
  20. scale := 1.0 / webpLimitShrink
  21. if err := img.Resize(scale, scale); err != nil {
  22. return err
  23. }
  24. log.Warningf("WebP dimension size is limited to %d. The image is rescaled to %dx%d", int(webpMaxDimension), img.Width(), img.Height())
  25. return nil
  26. }
  27. func fixHeifSize(img *vips.Image) error {
  28. heifLimitShrink := float64(max(img.Width(), img.Height())) / heifMaxDimension
  29. if heifLimitShrink <= 1.0 {
  30. return nil
  31. }
  32. scale := 1.0 / heifLimitShrink
  33. if err := img.Resize(scale, scale); err != nil {
  34. return err
  35. }
  36. log.Warningf("AVIF/HEIC dimension size is limited to %d. The image is rescaled to %dx%d", int(heifMaxDimension), img.Width(), img.Height())
  37. return nil
  38. }
  39. func fixGifSize(img *vips.Image) error {
  40. gifMaxResolution := float64(vips.GifResolutionLimit())
  41. gifResLimitShrink := float64(img.Width()*img.Height()) / gifMaxResolution
  42. gifDimLimitShrink := float64(max(img.Width(), img.Height())) / gifMaxDimension
  43. gifLimitShrink := math.Max(gifResLimitShrink, gifDimLimitShrink)
  44. if gifLimitShrink <= 1.0 {
  45. return nil
  46. }
  47. scale := math.Sqrt(1.0 / gifLimitShrink)
  48. if err := img.Resize(scale, scale); err != nil {
  49. return err
  50. }
  51. log.Warningf("GIF resolution is limited to %d and dimension size is limited to %d. The image is rescaled to %dx%d", int(gifMaxResolution), int(gifMaxDimension), img.Width(), img.Height())
  52. return nil
  53. }
  54. func fixIcoSize(img *vips.Image) error {
  55. icoLimitShrink := float64(max(img.Width(), img.Height())) / icoMaxDimension
  56. if icoLimitShrink <= 1.0 {
  57. return nil
  58. }
  59. scale := 1.0 / icoLimitShrink
  60. if err := img.Resize(scale, scale); err != nil {
  61. return err
  62. }
  63. log.Warningf("ICO dimension size is limited to %d. The image is rescaled to %dx%d", int(icoMaxDimension), img.Width(), img.Height())
  64. return nil
  65. }
  66. func fixSize(c *Context) error {
  67. switch c.PO.Format {
  68. case imagetype.WEBP:
  69. return fixWebpSize(c.Img)
  70. case imagetype.AVIF, imagetype.HEIC:
  71. return fixHeifSize(c.Img)
  72. case imagetype.GIF:
  73. return fixGifSize(c.Img)
  74. case imagetype.ICO:
  75. return fixIcoSize(c.Img)
  76. }
  77. return nil
  78. }