mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-10-10 04:02:29 +02:00
118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
package processing
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"math"
|
|
|
|
"github.com/imgproxy/imgproxy/v3/imagetype"
|
|
"github.com/imgproxy/imgproxy/v3/vips"
|
|
)
|
|
|
|
const (
|
|
// https://chromium.googlesource.com/webm/libwebp/+/refs/heads/master/src/webp/encode.h#529
|
|
webpMaxDimension = 16383.0
|
|
heifMaxDimension = 16384.0
|
|
gifMaxDimension = 65535.0
|
|
icoMaxDimension = 256.0
|
|
)
|
|
|
|
func fixWebpSize(img *vips.Image) error {
|
|
webpLimitShrink := float64(max(img.Width(), img.Height())) / webpMaxDimension
|
|
|
|
if webpLimitShrink <= 1.0 {
|
|
return nil
|
|
}
|
|
|
|
scale := 1.0 / webpLimitShrink
|
|
if err := img.Resize(scale, scale); err != nil {
|
|
return err
|
|
}
|
|
|
|
slog.Warn(fmt.Sprintf(
|
|
"WebP dimension size is limited to %d. The image is rescaled to %dx%d",
|
|
int(webpMaxDimension), img.Width(), img.Height(),
|
|
))
|
|
|
|
return nil
|
|
}
|
|
|
|
func fixHeifSize(img *vips.Image) error {
|
|
heifLimitShrink := float64(max(img.Width(), img.Height())) / heifMaxDimension
|
|
|
|
if heifLimitShrink <= 1.0 {
|
|
return nil
|
|
}
|
|
|
|
scale := 1.0 / heifLimitShrink
|
|
if err := img.Resize(scale, scale); err != nil {
|
|
return err
|
|
}
|
|
|
|
slog.Warn(fmt.Sprintf(
|
|
"AVIF/HEIC dimension size is limited to %d. The image is rescaled to %dx%d",
|
|
int(heifMaxDimension), img.Width(), img.Height(),
|
|
))
|
|
|
|
return nil
|
|
}
|
|
|
|
func fixGifSize(img *vips.Image) error {
|
|
gifMaxResolution := float64(vips.GifResolutionLimit())
|
|
gifResLimitShrink := float64(img.Width()*img.Height()) / gifMaxResolution
|
|
gifDimLimitShrink := float64(max(img.Width(), img.Height())) / gifMaxDimension
|
|
|
|
gifLimitShrink := math.Max(gifResLimitShrink, gifDimLimitShrink)
|
|
|
|
if gifLimitShrink <= 1.0 {
|
|
return nil
|
|
}
|
|
|
|
scale := math.Sqrt(1.0 / gifLimitShrink)
|
|
if err := img.Resize(scale, scale); err != nil {
|
|
return err
|
|
}
|
|
|
|
slog.Warn(fmt.Sprintf(
|
|
"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(),
|
|
))
|
|
|
|
return nil
|
|
}
|
|
|
|
func fixIcoSize(img *vips.Image) error {
|
|
icoLimitShrink := float64(max(img.Width(), img.Height())) / icoMaxDimension
|
|
|
|
if icoLimitShrink <= 1.0 {
|
|
return nil
|
|
}
|
|
|
|
scale := 1.0 / icoLimitShrink
|
|
if err := img.Resize(scale, scale); err != nil {
|
|
return err
|
|
}
|
|
|
|
slog.Warn(fmt.Sprintf(
|
|
"ICO dimension size is limited to %d. The image is rescaled to %dx%d",
|
|
int(icoMaxDimension), img.Width(), img.Height(),
|
|
))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *Processor) fixSize(c *Context) error {
|
|
switch c.PO.Format() {
|
|
case imagetype.WEBP:
|
|
return fixWebpSize(c.Img)
|
|
case imagetype.AVIF, imagetype.HEIC:
|
|
return fixHeifSize(c.Img)
|
|
case imagetype.GIF:
|
|
return fixGifSize(c.Img)
|
|
case imagetype.ICO:
|
|
return fixIcoSize(c.Img)
|
|
}
|
|
|
|
return nil
|
|
}
|