mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Use heic/avif embedded thumbnails
This commit is contained in:
parent
d1679b0046
commit
9b146991c5
@ -1,9 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
## Add
|
||||
### Add
|
||||
- Add support of RLE-encoded BMP.
|
||||
|
||||
### Change
|
||||
- Use thumbnail embedded to HEIC/AVIF if its size is larger than or equal to the requested.
|
||||
|
||||
## [3.4.0] - 2022-04-07
|
||||
### Add
|
||||
- Add `IMGPROXY_FALLBACK_IMAGE_TTL` config.
|
||||
|
@ -130,3 +130,7 @@ func (it Type) SupportsColourProfile() bool {
|
||||
it == WEBP ||
|
||||
it == AVIF
|
||||
}
|
||||
|
||||
func (it Type) SupportsThumbnail() bool {
|
||||
return it == HEIC || it == AVIF
|
||||
}
|
||||
|
@ -11,8 +11,12 @@ import (
|
||||
"github.com/imgproxy/imgproxy/v3/vips"
|
||||
)
|
||||
|
||||
func canScaleOnLoad(imgtype imagetype.Type, scale float64) bool {
|
||||
if imgtype == imagetype.SVG {
|
||||
func canScaleOnLoad(pctx *pipelineContext, imgdata *imagedata.ImageData, scale float64) bool {
|
||||
if imgdata == nil || pctx.trimmed || scale == 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
if imgdata.Type == imagetype.SVG {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -20,7 +24,10 @@ func canScaleOnLoad(imgtype imagetype.Type, scale float64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return imgtype == imagetype.JPEG || imgtype == imagetype.WEBP
|
||||
return imgdata.Type == imagetype.JPEG ||
|
||||
imgdata.Type == imagetype.WEBP ||
|
||||
imgdata.Type == imagetype.HEIC ||
|
||||
imgdata.Type == imagetype.AVIF
|
||||
}
|
||||
|
||||
func calcJpegShink(scale float64, imgtype imagetype.Type) int {
|
||||
@ -41,23 +48,45 @@ func calcJpegShink(scale float64, imgtype imagetype.Type) int {
|
||||
func scaleOnLoad(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
|
||||
prescale := math.Max(pctx.wscale, pctx.hscale)
|
||||
|
||||
if pctx.trimmed || prescale == 1 || imgdata == nil || !canScaleOnLoad(pctx.imgtype, prescale) {
|
||||
if !canScaleOnLoad(pctx, imgdata, prescale) {
|
||||
return nil
|
||||
}
|
||||
|
||||
jpegShrink := calcJpegShink(prescale, pctx.imgtype)
|
||||
var newWidth, newHeight int
|
||||
|
||||
if pctx.imgtype == imagetype.JPEG && jpegShrink == 1 {
|
||||
return nil
|
||||
}
|
||||
if imgdata.Type.SupportsThumbnail() {
|
||||
thumbnail := new(vips.Image)
|
||||
defer thumbnail.Clear()
|
||||
|
||||
if err := img.Load(imgdata, jpegShrink, prescale, 1); err != nil {
|
||||
return err
|
||||
if err := thumbnail.LoadThumbnail(imgdata); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// Update scales after scale-on-load
|
||||
newWidth, newHeight, _, _ := extractMeta(img, po.Rotate, po.AutoRotate)
|
||||
|
||||
wpreshrink := float64(pctx.srcWidth) / float64(newWidth)
|
||||
hpreshrink := float64(pctx.srcHeight) / float64(newHeight)
|
||||
|
||||
|
@ -82,8 +82,13 @@ vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out) {
|
||||
}
|
||||
|
||||
int
|
||||
vips_heifload_go(void *buf, size_t len, VipsImage **out) {
|
||||
return vips_heifload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
vips_heifload_go(void *buf, size_t len, VipsImage **out, int thumbnail) {
|
||||
return vips_heifload_buffer(
|
||||
buf, len, out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"thumbnail", thumbnail,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
|
25
vips/vips.go
25
vips/vips.go
@ -229,7 +229,7 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
||||
case imagetype.SVG:
|
||||
err = C.vips_svgload_go(data, dataSize, C.double(scale), &tmp)
|
||||
case imagetype.HEIC, imagetype.AVIF:
|
||||
err = C.vips_heifload_go(data, dataSize, &tmp)
|
||||
err = C.vips_heifload_go(data, dataSize, &tmp, C.int(0))
|
||||
case imagetype.TIFF:
|
||||
err = C.vips_tiffload_go(data, dataSize, &tmp)
|
||||
default:
|
||||
@ -244,6 +244,25 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) LoadThumbnail(imgdata *imagedata.ImageData) error {
|
||||
if imgdata.Type != imagetype.HEIC && imgdata.Type != imagetype.AVIF {
|
||||
return errors.New("Usupported image type to load thumbnail")
|
||||
}
|
||||
|
||||
var tmp *C.VipsImage
|
||||
|
||||
data := unsafe.Pointer(&imgdata.Data[0])
|
||||
dataSize := C.size_t(len(imgdata.Data))
|
||||
|
||||
if err := C.vips_heifload_go(data, dataSize, &tmp, C.int(1)); err != 0 {
|
||||
return Error()
|
||||
}
|
||||
|
||||
C.swap_and_clear(&img.VipsImage, tmp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) Save(imgtype imagetype.Type, quality int) (*imagedata.ImageData, error) {
|
||||
if imgtype == imagetype.ICO {
|
||||
return img.saveAsIco()
|
||||
@ -314,6 +333,10 @@ func (img *Image) Arrayjoin(in []*Image) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) Swap(in *Image) {
|
||||
img.VipsImage, in.VipsImage = in.VipsImage, img.VipsImage
|
||||
}
|
||||
|
||||
func (img *Image) IsAnimated() bool {
|
||||
return C.vips_is_animated(img.VipsImage) > 0
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ int vips_pngload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_webpload_go(void *buf, size_t len, double scale, int pages, 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);
|
||||
int vips_heifload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_heifload_go(void *buf, size_t len, VipsImage **out, int thumbnail);
|
||||
int vips_tiffload_go(void *buf, size_t len, VipsImage **out);
|
||||
|
||||
int vips_black_go(VipsImage **out, int width, int height, int bands);
|
||||
|
Loading…
Reference in New Issue
Block a user