mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-25 19:24:38 +02:00
Optimize watermark application
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
### Change
|
||||
- Optimized memory buffers pooling for better performance and memory reusage.
|
||||
- Optimized watermarks application.
|
||||
|
||||
## [3.16.1] - 2023-04-26
|
||||
### Fix
|
||||
|
@@ -67,17 +67,6 @@ func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options
|
||||
if err := wm.Replicate(imgWidth, imgHeight); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
left, top := calcPosition(imgWidth, imgHeight, wm.Width(), wm.Height(), &opts.Gravity, offsetScale, true)
|
||||
if err := wm.Embed(imgWidth, imgHeight, left, top); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if framesCount > 1 {
|
||||
if err := wm.Replicate(imgWidth, imgWidth*framesCount); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
wm.RemoveHeader("palette-bit-depth")
|
||||
@@ -95,14 +84,38 @@ func applyWatermark(img *vips.Image, wmData *imagedata.ImageData, opts *options.
|
||||
|
||||
width := img.Width()
|
||||
height := img.Height()
|
||||
frameHeight := height / framesCount
|
||||
|
||||
if err := prepareWatermark(wm, wmData, opts, width, height/framesCount, offsetScale, framesCount); err != nil {
|
||||
if err := prepareWatermark(wm, wmData, opts, width, frameHeight, offsetScale, framesCount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opacity := opts.Opacity * config.WatermarkOpacity
|
||||
|
||||
return img.ApplyWatermark(wm, opacity)
|
||||
// If we replicated the watermark and need to apply it to an animated image,
|
||||
// it is faster to replicate the watermark to all the image and apply it single-pass
|
||||
if opts.Replicate && framesCount > 1 {
|
||||
if err := wm.Replicate(width, height); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return img.ApplyWatermark(wm, 0, 0, opacity)
|
||||
}
|
||||
|
||||
left, top := 0, 0
|
||||
|
||||
if !opts.Replicate {
|
||||
left, top = calcPosition(width, frameHeight, wm.Width(), wm.Height(), &opts.Gravity, offsetScale, true)
|
||||
}
|
||||
|
||||
for i := 0; i < framesCount; i++ {
|
||||
if err := img.ApplyWatermark(wm, left, top, opacity); err != nil {
|
||||
return err
|
||||
}
|
||||
top += frameHeight
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func watermark(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
|
||||
|
@@ -531,7 +531,7 @@ vips_embed_go(VipsImage *in, VipsImage **out, int x, int y, int width, int heigh
|
||||
}
|
||||
|
||||
int
|
||||
vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, double opacity) {
|
||||
vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, int left, int top, double opacity) {
|
||||
VipsImage *base = vips_image_new();
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 7);
|
||||
|
||||
@@ -559,7 +559,11 @@ vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, doubl
|
||||
int had_alpha = vips_image_hasalpha(in);
|
||||
|
||||
if (
|
||||
vips_composite2(in, watermark, &t[5], VIPS_BLEND_MODE_OVER, "compositing_space", in->Type, NULL) ||
|
||||
vips_composite2(
|
||||
in, watermark, &t[5], VIPS_BLEND_MODE_OVER,
|
||||
"x", left, "y", top, "compositing_space", in->Type,
|
||||
NULL
|
||||
) ||
|
||||
vips_cast(t[5], &t[6], vips_image_get_format(in), NULL)
|
||||
) {
|
||||
clear_image(&base);
|
||||
|
@@ -771,10 +771,10 @@ func (img *Image) Embed(width, height int, offX, offY int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) ApplyWatermark(wm *Image, opacity float64) error {
|
||||
func (img *Image) ApplyWatermark(wm *Image, left, top int, opacity float64) error {
|
||||
var tmp *C.VipsImage
|
||||
|
||||
if C.vips_apply_watermark(img.VipsImage, wm.VipsImage, &tmp, C.double(opacity)) != 0 {
|
||||
if C.vips_apply_watermark(img.VipsImage, wm.VipsImage, &tmp, C.int(left), C.int(top), C.double(opacity)) != 0 {
|
||||
return Error()
|
||||
}
|
||||
C.swap_and_clear(&img.VipsImage, tmp)
|
||||
|
@@ -67,7 +67,8 @@ int vips_flatten_go(VipsImage *in, VipsImage **out, double r, double g, double b
|
||||
int vips_replicate_go(VipsImage *in, VipsImage **out, int across, int down);
|
||||
int vips_embed_go(VipsImage *in, VipsImage **out, int x, int y, int width, int height);
|
||||
|
||||
int vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, double opacity);
|
||||
int vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out,
|
||||
int left, int top, double opacity);
|
||||
|
||||
int vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n);
|
||||
|
||||
|
Reference in New Issue
Block a user