This is a Python 2.7 code recipe for applying a semi-transparent vector (SVG) watermark with overlay blending like so:
What’s special about it:
- The watermark is a vector image (SVG), which means it’d look sharp when placed on images of any sizes. The function scales the watermark proportionally to the width of the source image.
- Supports blending modes (what’s that?), including my favorite “overlay”.
- Watermark transparency level is a function argument. SVG transparency is also supported, so different parts of the watermark can have varying opaqueness.
Prerequisites: Wand, imagemagick (for Wand) and librsvg:
sudo apt-get/yum install librsvg imagemagick
If you’re on OS X and use Homebrew: brew install librsvg imagemagick
Install Wand using pip: pip install wand
Make sure rsvg-convert
command is available in your shell.
import subprocess
from wand.image import Image as WandImage
def watermark(source, target, watermark, blend_mode='overlay', ratio=1, transparency=0.3):
source_obj = WandImage(filename=source)
watermark_obj = WandImage(filename=watermark)
if ratio > 1:
ratio = 1
watermark_width = int(source_obj.size[0] * ratio)
watermark_height = int(float(watermark_width) / float(watermark_obj.size[0]) * watermark_obj.size[1])
rsvg = subprocess.Popen(
['rsvg-convert', '-a', '-h', str(watermark_height), watermark],
stdout=subprocess.PIPE
)
watermark_obj = WandImage(blob=rsvg.stdout.read())
del rsvg
watermark_obj.transparentize(transparency)
source_obj.composite_channel(
'all_channels', watermark_obj, blend_mode,
source_obj.size[0] / 2 - watermark_obj.size[0] / 2,
source_obj.size[1] / 2 - watermark_obj.size[1] / 2
)
source_obj.save(filename=target)
return True
Minimal usage:
watermark('photo.jpg', 'photo+watermark.jpg', 'watermark.svg')
Why do you use librsvg? Because Imagemagick (which we use via Wand) isn’t as flexible when it comes to scaling vectors. When you ask Imagemagick to scale an SVG, it converts it to a raster PNG of arbitrary size and then scales the PNG, often making it very blurry.
Why don’t you use some librsvg binding? Because it works fine from subprocess and I’m lazy.
What other blend modes are available? See Wand docs under wand.image.COMPOSITE_OPERATORS
.
Thanks to Alexander Norov who has helped me assemble this code.
License: MIT.
pip install librsvg
not working for windows system
It seems librsvg isn’t available for Windows at all. But even if it was, I’m not sure my code would work on Windows because it relies on subprocess, sorry.
Mind if I ask what’s the font you used for example.com watermark (https://dae.me/storage/images/watermark.svg)?
And what tools did you use to create this svg? I’ve tried 5 different png to svg converters and they all failed :(
The font is probably Proxima Nova. I used Adobe Illustrator CC. PNG is a raster image, SVG contains vectors. Vectors can be scaled and this is cool because photos come in different sizes. Some photos are really big, some are small, yet the watermark should look crisp and sharp on either. PNG cannot be used the same way, but if your photos are the same size and you don’t need to scale the watermark, its perfectly fine to use PNG.