1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-01-23 11:14:48 +02:00
imgproxy/processing/scale_on_load.go

119 lines
2.7 KiB
Go
Raw Normal View History

2021-04-26 17:52:50 +06:00
package processing
import (
"math"
2022-06-10 16:52:35 +06:00
log "github.com/sirupsen/logrus"
2021-09-30 20:23:30 +06:00
"github.com/imgproxy/imgproxy/v3/config"
"github.com/imgproxy/imgproxy/v3/imagedata"
"github.com/imgproxy/imgproxy/v3/imagetype"
"github.com/imgproxy/imgproxy/v3/imath"
"github.com/imgproxy/imgproxy/v3/options"
"github.com/imgproxy/imgproxy/v3/vips"
2021-04-26 17:52:50 +06:00
)
2022-04-14 21:41:00 +06:00
func canScaleOnLoad(pctx *pipelineContext, imgdata *imagedata.ImageData, scale float64) bool {
if imgdata == nil || pctx.trimmed || scale == 1 {
return false
}
if imgdata.Type == imagetype.SVG {
2021-04-26 17:52:50 +06:00
return true
}
if config.DisableShrinkOnLoad || scale >= 1 {
return false
}
2022-04-14 21:41:00 +06:00
return imgdata.Type == imagetype.JPEG ||
imgdata.Type == imagetype.WEBP ||
imgdata.Type == imagetype.HEIC ||
imgdata.Type == imagetype.AVIF
2021-04-26 17:52:50 +06:00
}
func calcJpegShink(scale float64, imgtype imagetype.Type) int {
shrink := int(1.0 / scale)
switch {
case shrink >= 8:
return 8
case shrink >= 4:
return 4
case shrink >= 2:
return 2
}
return 1
}
func scaleOnLoad(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
prescale := math.Max(pctx.wscale, pctx.hscale)
2022-04-14 21:41:00 +06:00
if !canScaleOnLoad(pctx, imgdata, prescale) {
2021-04-26 17:52:50 +06:00
return nil
}
2022-04-14 21:41:00 +06:00
var newWidth, newHeight int
2021-04-26 17:52:50 +06:00
2022-04-14 21:41:00 +06:00
if imgdata.Type.SupportsThumbnail() {
thumbnail := new(vips.Image)
defer thumbnail.Clear()
if err := thumbnail.LoadThumbnail(imgdata); err != nil {
2022-06-10 16:52:35 +06:00
log.Debugf("Can't load thumbnail: %s", err)
return nil
2022-04-14 21:41:00 +06:00
}
2021-04-26 17:52:50 +06:00
2022-04-14 21:41:00 +06:00
angle, flip := 0, false
newWidth, newHeight, angle, flip = extractMeta(thumbnail, po.Rotate, po.AutoRotate)
if newWidth >= pctx.srcWidth || float64(newWidth)/float64(pctx.srcWidth) < prescale {
return nil
}
img.Swap(thumbnail)
pctx.angle = angle
pctx.flip = flip
} else {
jpegShrink := calcJpegShink(prescale, pctx.imgtype)
if pctx.imgtype == imagetype.JPEG && jpegShrink == 1 {
return nil
}
if err := img.Load(imgdata, jpegShrink, prescale, 1); err != nil {
return err
}
newWidth, newHeight, _, _ = extractMeta(img, po.Rotate, po.AutoRotate)
2021-04-26 17:52:50 +06:00
}
// Update scales after scale-on-load
2022-01-17 18:39:59 +06:00
wpreshrink := float64(pctx.srcWidth) / float64(newWidth)
hpreshrink := float64(pctx.srcHeight) / float64(newHeight)
pctx.wscale = wpreshrink * pctx.wscale
if newWidth == imath.Scale(newWidth, pctx.wscale) {
2021-04-26 17:52:50 +06:00
pctx.wscale = 1.0
}
2022-01-17 18:39:59 +06:00
pctx.hscale = hpreshrink * pctx.hscale
if newHeight == imath.Scale(newHeight, pctx.hscale) {
2021-04-26 17:52:50 +06:00
pctx.hscale = 1.0
}
2022-01-17 18:39:59 +06:00
if pctx.cropWidth > 0 {
pctx.cropWidth = imath.Max(1, imath.Shrink(pctx.cropWidth, wpreshrink))
}
if pctx.cropHeight > 0 {
pctx.cropHeight = imath.Max(1, imath.Shrink(pctx.cropHeight, hpreshrink))
}
if pctx.cropGravity.Type != options.GravityFocusPoint {
pctx.cropGravity.X /= wpreshrink
pctx.cropGravity.Y /= hpreshrink
}
2021-04-26 17:52:50 +06:00
return nil
}