mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-10-02 17:09:48 +02:00
Optimize watermark application
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
### Change
|
### Change
|
||||||
- Optimized memory buffers pooling for better performance and memory reusage.
|
- Optimized memory buffers pooling for better performance and memory reusage.
|
||||||
|
- Optimized watermarks application.
|
||||||
|
|
||||||
## [3.16.1] - 2023-04-26
|
## [3.16.1] - 2023-04-26
|
||||||
### Fix
|
### Fix
|
||||||
|
@@ -67,17 +67,6 @@ func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options
|
|||||||
if err := wm.Replicate(imgWidth, imgHeight); err != nil {
|
if err := wm.Replicate(imgWidth, imgHeight); err != nil {
|
||||||
return err
|
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")
|
wm.RemoveHeader("palette-bit-depth")
|
||||||
@@ -95,14 +84,38 @@ func applyWatermark(img *vips.Image, wmData *imagedata.ImageData, opts *options.
|
|||||||
|
|
||||||
width := img.Width()
|
width := img.Width()
|
||||||
height := img.Height()
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity := opts.Opacity * config.WatermarkOpacity
|
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 {
|
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
|
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 *base = vips_image_new();
|
||||||
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 7);
|
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);
|
int had_alpha = vips_image_hasalpha(in);
|
||||||
|
|
||||||
if (
|
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)
|
vips_cast(t[5], &t[6], vips_image_get_format(in), NULL)
|
||||||
) {
|
) {
|
||||||
clear_image(&base);
|
clear_image(&base);
|
||||||
|
@@ -771,10 +771,10 @@ func (img *Image) Embed(width, height int, offX, offY int) error {
|
|||||||
return nil
|
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
|
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()
|
return Error()
|
||||||
}
|
}
|
||||||
C.swap_and_clear(&img.VipsImage, tmp)
|
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_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_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);
|
int vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user