How to Watermark Your Photos with Python

When you look up photos online, you will notice that some of them are watermarked. A watermark is usually some text or a logo overlaid on the photo that identifies who took the photo or who owns the rights to the photo. Some professionals recommend adding watermarks to your photos before sharing them on social media to prevent other people from using your photos as their own and profiting off your work. Of course, watermarking can be removed fairly easily, so this isn’t as useful as it used to be as a digital rights tool.

Anyway, the Pillow package provides the tools you need to add watermarks to your photos! The first thing you need to do is install Pillow if you haven’t already:

pip install pillow

Once that’s installed, we can continue!


Adding a Text Watermark

We will start by just adding some text to a photograph. Let’s use this one of a the Yequina lighthouse that I took in Oregon:

Now we will add some text to the image. In this case, let’s add my domain to it: www.mousevspython.com

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont


def watermark_text(input_image_path,
                   output_image_path,
                   text, pos):
    photo = Image.open(input_image_path)

    # make the image editable
    drawing = ImageDraw.Draw(photo)

    black = (3, 8, 12)
    font = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
    drawing.text(pos, text, fill=black, font=font)
    photo.show()
    photo.save(output_image_path)


if __name__ == '__main__':
    img = 'lighthouse.jpg'
    watermark_text(img, 'lighthouse_watermarked.jpg',
                   text='www.mousevspython.com',
                   pos=(0, 0))

Here we import a few classes from PIL: Image, ImageDraw and ImageFont. Then we create a function, watermark_text, that takes four arguments: the input image page, the output image path, the text to add to the image, and the position coordinates to put the text in.

Next we open our image. Then we basically make a copy of the image by redrawing it using the ImageDraw.Draw method. This allows us to add text to it more easily. Then we create a font using ImageFont.truetype. The font is one that is included with the Pillow library. We set the font size to 40 points as well. Finally we show the result and save it to disk. Here is the result:

Now let’s move on to add an image instead of just text!


Watermark with an Image

Most professional photographers end up watermarking their photos with a logo. Sometimes that includes a stylized “photo” version of their website. Adding a photo to another photo in Pillow is also quite easy. Let’s find out how to do it!

In this example, we will use one of my logos for the watermark image.

from PIL import Image

def watermark_photo(input_image_path,
                    output_image_path,
                    watermark_image_path,
                    position):
    base_image = Image.open(input_image_path)
    watermark = Image.open(watermark_image_path)

    # add watermark to your image
    base_image.paste(watermark, position)
    base_image.show()
    base_image.save(output_image_path)

if __name__ == '__main__':
    img = 'lighthouse.jpg'
    watermark_with_photo(img, 'lighthouse_watermarked2.jpg',
                         'watermark.png', position=(0,0))

Here we create a function that is very similar to the function in the last section, but instead of passing in text, we pass in the watermark’s file path. In the function, we open up the image we wish to watermark as well as the watermark image itself. Then we take the image to be watermarked and call its paste() method while passing in what we want to paste (i.e. the watermark) and the position we want the item pasted. Finally we show the image and save it. Here’s the result:

Well that didn’t work out the way I had envisioned it. As you can see, there’s a black background obscuring a lot more of the photo than I intended because when we pasted it, we didn’t account for transparency.


Watermark an Image with Transparency

Let’s create a new function that can use transparency so we remove all the black from the watermark. I found a solution for this issue on StackOverflow, so I took it and modified it slightly for this example

from PIL import Image

def watermark_with_transparency(input_image_path,
                                output_image_path,
                                watermark_image_path,
                                position):
    base_image = Image.open(input_image_path)
    watermark = Image.open(watermark_image_path)
    width, height = base_image.size

    transparent = Image.new('RGBA', (width, height), (0,0,0,0))
    transparent.paste(base_image, (0,0))
    transparent.paste(watermark, position, mask=watermark)
    transparent.show()
    transparent.save(output_image_path)


if __name__ == '__main__':
    img = 'lighthouse.jpg'
    watermark_with_transparency(img, 'lighthouse_watermarked3.jpg',
                                'watermark.png', position=(0,0))

In this code, we take in all the same arguments that we did in the previous example. This time we not only open up both images, but we also grab the width and height of the image that we want to watermark. Then we create a new image using the same width and height as the image we are watermarking. You will note that this image that we create is RGBA which means it has Red, Green and Blue with Alpha. Next we paste in the image we want to watermark starting at the upper left, which is (0,0). Then we paste in our watermark using the passed in position and we also mask the watermark with itself. Finally we show and save the image.

The resulting image looks like this:

Pretty cool, eh?


Wrapping Up

We covered 2 different methods of adding watermarks to your photographs in this article. In the first example, all we did was add the text of your choice to the image. The second example demonstrated a way to add an image watermark, but it didn’t account for alpha (transparency). We corrected that issue with the third example. I hope you found these examples helpful. Happy coding!


Related Reading