mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-02-07 11:36:25 +02:00
Better scale-on-load for WebP with libvips 8.8
This commit is contained in:
parent
eb60f0567c
commit
3fb3a327a3
59
process.go
59
process.go
@ -230,21 +230,28 @@ func calcScale(width, height int, po *processingOptions, imgtype imageType) floa
|
||||
return scale
|
||||
}
|
||||
|
||||
func calcShink(scale float64, imgtype imageType) int {
|
||||
switch imgtype {
|
||||
case imageTypeWEBP:
|
||||
return int(1.0 / scale)
|
||||
case imageTypeJPEG:
|
||||
shrink := int(1.0 / scale)
|
||||
func canScaleOnLoad(imgtype imageType, scale float64) bool {
|
||||
if imgtype == imageTypeSVG {
|
||||
return true
|
||||
}
|
||||
|
||||
switch {
|
||||
case shrink >= 8:
|
||||
return 8
|
||||
case shrink >= 4:
|
||||
return 4
|
||||
case shrink >= 2:
|
||||
return 2
|
||||
}
|
||||
if conf.DisableShrinkOnLoad || scale >= 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return imgtype == imageTypeJPEG || imgtype == imageTypeWEBP
|
||||
}
|
||||
|
||||
func calcJpegShink(scale float64, imgtype imageType) int {
|
||||
shrink := int(1.0 / scale)
|
||||
|
||||
switch {
|
||||
case shrink >= 8:
|
||||
return 8
|
||||
case shrink >= 4:
|
||||
return 4
|
||||
case shrink >= 2:
|
||||
return 2
|
||||
}
|
||||
|
||||
return 1
|
||||
@ -292,28 +299,28 @@ func transformImage(ctx context.Context, img **C.VipsImage, data []byte, po *pro
|
||||
|
||||
scale := calcScale(imgWidth, imgHeight, po, imgtype)
|
||||
|
||||
if scale != 1 && data != nil {
|
||||
if imgtype == imageTypeSVG {
|
||||
// Load SVG with desired scale
|
||||
if scale != 1 && data != nil && canScaleOnLoad(imgtype, scale) {
|
||||
if imgtype == imageTypeWEBP || imgtype == imageTypeSVG {
|
||||
// Do some scale-on-load
|
||||
if tmp, err := vipsLoadImage(data, imgtype, 1, scale, false); err == nil {
|
||||
C.swap_and_clear(img, tmp)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
scale = 1
|
||||
} else if !conf.DisableShrinkOnLoad && scale < 1.0 {
|
||||
} else if imgtype == imageTypeJPEG {
|
||||
// Do some shrink-on-load
|
||||
if shrink := calcShink(scale, imgtype); shrink != 1 {
|
||||
if shrink := calcJpegShink(scale, imgtype); shrink != 1 {
|
||||
if tmp, err := vipsLoadImage(data, imgtype, shrink, 1.0, false); err == nil {
|
||||
C.swap_and_clear(img, tmp)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
scale = scale * float64(shrink)
|
||||
}
|
||||
}
|
||||
|
||||
// Update actual image size ans scale after scale-on-load
|
||||
imgWidth, imgHeight, _, _ = extractMeta(*img)
|
||||
scale = calcScale(imgWidth, imgHeight, po, imgtype)
|
||||
}
|
||||
|
||||
if err = vipsRad2Float(img); err != nil {
|
||||
@ -628,7 +635,7 @@ func vipsPrepareWatermark() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func vipsLoadImage(data []byte, imgtype imageType, shrink int, svgScale float64, allPages bool) (*C.VipsImage, error) {
|
||||
func vipsLoadImage(data []byte, imgtype imageType, shrink int, scale float64, allPages bool) (*C.VipsImage, error) {
|
||||
var img *C.VipsImage
|
||||
|
||||
err := C.int(0)
|
||||
@ -639,7 +646,7 @@ func vipsLoadImage(data []byte, imgtype imageType, shrink int, svgScale float64,
|
||||
case imageTypePNG:
|
||||
err = C.vips_pngload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img)
|
||||
case imageTypeWEBP:
|
||||
err = C.vips_webpload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(shrink), &img)
|
||||
err = C.vips_webpload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(scale), &img)
|
||||
case imageTypeGIF:
|
||||
pages := C.int(1)
|
||||
if allPages {
|
||||
@ -648,7 +655,7 @@ func vipsLoadImage(data []byte, imgtype imageType, shrink int, svgScale float64,
|
||||
|
||||
err = C.vips_gifload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), pages, &img)
|
||||
case imageTypeSVG:
|
||||
err = C.vips_svgload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(svgScale), &img)
|
||||
err = C.vips_svgload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(scale), &img)
|
||||
case imageTypeICO:
|
||||
rawData, width, height, icoErr := icoData(data)
|
||||
if icoErr != nil {
|
||||
|
18
vips.c
18
vips.c
@ -19,6 +19,9 @@
|
||||
#define VIPS_SUPPORT_PNG_QUANTIZATION \
|
||||
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 7))
|
||||
|
||||
#define VIPS_SUPPORT_WEBP_SCALE_ON_LOAD \
|
||||
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||
|
||||
#define VIPS_SUPPORT_BUILTIN_ICC \
|
||||
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||
|
||||
@ -102,9 +105,18 @@ vips_pngload_go(void *buf, size_t len, VipsImage **out) {
|
||||
}
|
||||
|
||||
int
|
||||
vips_webpload_go(void *buf, size_t len, int shrink, VipsImage **out) {
|
||||
if (shrink > 1)
|
||||
return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, "shrink", shrink, NULL);
|
||||
vips_webpload_go(void *buf, size_t len, double scale, VipsImage **out) {
|
||||
if (scale < 1)
|
||||
return vips_webpload_buffer(
|
||||
buf, len, out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
#if VIPS_SUPPORT_WEBP_SCALE_ON_LOAD
|
||||
"scale", scale,
|
||||
#else
|
||||
"shrink", (int)(1.0 / scale),
|
||||
#endif
|
||||
NULL
|
||||
);
|
||||
|
||||
return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
}
|
||||
|
2
vips.h
2
vips.h
@ -25,7 +25,7 @@ int vips_type_find_save_go(int imgtype);
|
||||
|
||||
int vips_jpegload_go(void *buf, size_t len, int shrink, VipsImage **out);
|
||||
int vips_pngload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_webpload_go(void *buf, size_t len, int shrink, VipsImage **out);
|
||||
int vips_webpload_go(void *buf, size_t len, double scale, VipsImage **out);
|
||||
int vips_gifload_go(void *buf, size_t len, int pages, VipsImage **out);
|
||||
int vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user