Optimize watermark application

This commit is contained in:
DarthSim
2023-05-10 17:46:02 +03:00
parent e8952edbf7
commit 85f790fb4b
5 changed files with 37 additions and 18 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);