libvips / pyvips

python binding for libvips using cffi
MIT License
649 stars 50 forks source link

Segment fault when use composite2 multiple times to add repeated watermarks to image #283

Open lanyusan opened 3 years ago

lanyusan commented 3 years ago

I have a use case that needs to add watermarks to large images multiple times to create watermark patterns that spreads on destination image.

The code is very simple. Just call this multiple times, with different tx, and ty.

 target_image = target_image.composite2(source_image, pyvips.enums.BlendMode.OVER, x = tx,y = ty, premultiplied=True)

This was called around 100 times. Then this error:

 Fatal Python error: Segmentation fault

Current thread 0x00007f150e7b8280 (most recent call first):

  File ".../site-packages/pyvips/voperation.py", line 290 in call
  File ".../site-packages/pyvips/vimage.py", line 921 in call_function

What's the most efficient way to create patterned watermarks?

Thanks for the great library by the way. It works very well in other senarios.

jcupitt commented 3 years ago

Hi @lanyusan,

It depends what you're trying to do. You can composite many images in a single composite, perhaps that would do what you need?

If the images are in a regular grid, one easy way is to use replicate to make an overlay, for example:

#!/usr/bin/python3

import sys
import pyvips

im = pyvips.Image.new_from_file(sys.argv[1], access="sequential")

# make the watermark 
text = pyvips.Image.text(sys.argv[3], width = 500, dpi = 300).rotate(45)
blue = text.new_from_image([128, 128, 255]).copy(interpretation ="srgb")
# use the text as the alpha, scaled down to make it semi-transparent
text = blue.bandjoin(text * 0.3).cast("uchar")

# replicate many times to cover the image
overlay = text \
        .replicate(1 + im.width / text.width, 1 + im.height / text.height) \
        .crop(0, 0, im.width, im.height)

# composite on top of the image
im = im.composite(overlay, "over")

im.write_to_file(sys.argv[2])

Run with:

$ ./watermark.py ~/pics/Gugg_coloured.jpg x.jpg hello

To make:

x

lanyusan commented 3 years ago

Thanks for the quick response. This works for me.