Welcome to a quick tutorial on how to add a watermark to an image in Python. Want to automatically add a watermark to images in Python? Well, it is thankfully easy – Let us walk through some examples in this guide. Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TLDR – QUICK SLIDES
Fullscreen Mode – Click Here
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
- Download and unzip into your project folder, create a virtual environment for your project as usual.
virualenv/venv
- Windows –
venv\scripts\activate
- Mac/Linux –
venv/bin/activate
- Install the required modules –
pip install pillow
- Run the examples –
S1_text.py
Text watermarkS2_image.py
Image watermarkS3_center.py
Centered image watermark
EXAMPLE CODE DOWNLOAD
Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
PYTHON WATERMARK IMAGES
All right, let us now get into the examples of adding a watermark to images in Python.
EXAMPLE 1) SIMPLE TEXT WATERMARK
# (A) REQUIRED MODULES
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# (B) SETTINGS
# (B1) TEXT SETTINGS
txt = "Copyright" # text to write
txtFont = ImageFont.truetype("c:/windows/arial.ttf", 60) # font & font size
txtColor = (255, 255, 255) # text color
txtCoord = (0, 0) # place the text here
# (B2) SAVE SETTINGS
source = "source.webp" # source image
target = "demoA.webp" # save to this file
quality = 90 # image quality
# (C) DRAW TEXT & SAVE
img = Image.open(source)
ImageDraw.Draw(img).text(txtCoord, txt, font=txtFont, fill=txtColor)
img.save(target, format="webp", quality=quality)
- Load the pillow image library. Captain Obvious at your service.
- A whole bunch of settings, these should be self-explanatory when you read through them one by one.
- Yep, 3 lines are all we need to “embed” a watermark.
img = Image.open(source)
Open the source image.ImageDraw.Draw(img).text(...)
Draw text onto the source image.img.save()
Save the processed image. The end.
EXAMPLE 2) IMAGE WATERMARK
# (A) REQUIRED MODULES
from PIL import Image
# (B) SETTINGS
source = "source.webp" # source image
watermark = "watermark.png" # watermark image
target = "demoB.webp" # save to this file
quality = 90 # image quality
# (C) DRAW WATERMARK & SAVE
imgS = Image.open(source).convert("RGBA")
imgW = Image.open(watermark)
imgS.paste(imgW, (0,0), imgW.convert("RGBA"))
imgS.save(target, format="webp", quality=quality)
- Load the Pillow Image Library.
- The file name of the source image, watermark image (best to have a transparent background), and processed image.
- That’s right. We are pretty much opening both the source and watermark images here, then just paste the watermark onto the source.
P.S. paste()
takes in 3 parameters – First is the image to paste, second are the coordinates of where to paste it to, and the last is the transparency mask… Let’s keep things simple and just say that the last one is necessary to properly render the watermark’s transparent background.
EXAMPLE 3) CENTERED WATERMARK
# (A) REQUIRED MODULES
from PIL import Image
# (B) SETTINGS
source = "source.webp" # source image
watermark = "watermark.png" # watermark image
target = "demoC.webp" # save to this file
quality = 90 # image quality
# (C) CALCULATE CENTER
imgS = Image.open(source).convert("RGBA")
imgW = Image.open(watermark)
dimSX, dimSY = imgS.size
dimWX, dimWY = imgW.size
center = ((dimSX - dimWX) // 2, (dimSY - dimWY) // 2)
# (D) DRAW WATERMARK & SAVE
imgS.paste(imgW, center, imgW.convert("RGBA"))
imgS.save(target, format="webp", quality=quality)
It’s pretty much the same “paste watermark onto source image”, but remember that we can specify where to paste the watermark. So in section (C), we calculate the exact center coordinates. For those who don’t catch it, it’s simply – (SOURCE WIDTH/HEIGHT - WATERMARK WIDTH/HEIGHT) ÷ 2
.
EXTRA BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
EXTRA – TRANSPARENT TEXT
imgA = Image.open(source).convert("RGBA")
imgB = Image.new("RGBA", imgA.size, (255, 255, 255, 0))
ImageDraw.Draw(imgB).text((0,0), "TEXT", font="FONT.TTF", fill=(0, 0, 0, 128))
imgC = Image.alpha_composite(imgA, imgB)
imgC.show()
Yes, we can draw transparent text. As from the example on the official Pillow menu –
- We create 2 layers –
imgA
is the source image,imgB
is for the text. - Write text onto
imgB
– Take note that we specify the opacity now. - Composite (combine)
imgA
andimgB
, save it.
LINKS & REFERENCES
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!