Skip to content

Instantly share code, notes, and snippets.

@TApicella
Last active July 23, 2016 01:45
Show Gist options
  • Save TApicella/f15a5c5f7aa7ee5ce3e328b1810e42ed to your computer and use it in GitHub Desktop.
Save TApicella/f15a5c5f7aa7ee5ce3e328b1810e42ed to your computer and use it in GitHub Desktop.
A script that adds a watermark to the bottom right of each picture in a directory of pictures
from PIL import Image, ImageDraw
import os, math
#SETTINGS
WIDTH_RATIO = 3 #Ratio of image min width to watermark width
MIN_WIDTH = 200 #Minimum width of watermark. In my watermark, it is 1/3 of the normal width
MIN_HEIGHT = 40 #Minimum height of watermark. In my watermark ,it is 1/3 of the normal height
WATERMARK_LOCATION = "watermark.png"
#Most helpful source: http://stackoverflow.com/questions/13662184/python-pil-lighten-transparent-image-and-paste-to-another-one
def add_watermark(photo, wm_img):
if photo == wm_img.split("\\")[-1]:
print "%s is watermark" % photo
return
elif "_wm.png" in photo or "_wm.jpg" in photo:
print "%s is already watermarked" % photo
return
print "Processing %s" % photo
# Open the original image
main = Image.open(photo)
watermark = Image.open(wm_img)
main_size = main.size
wm_size = watermark.size
resize_side = min(main.size[0], main.size[1])
resize_width = (int)(resize_side/WIDTH_RATIO)
resize_ratio = (float)(resize_width)/((float)(wm_size[0]))
resize_height = (int)(wm_size[1]*resize_ratio)
if resize_width <= MIN_WIDTH:
resize_width = MIN_WIDTH
resize_height = MIN_HEIGHT
watermark = watermark.resize((resize_width, resize_height))
x_offset = main_size[0]-resize_width
y_offset = main_size[1]-resize_height
#Estimate watermark area "chaoticness"
pixel_count = 0
shift_count = 0
prev_pixel_up = None
prev_pixel_left = None
if main.mode == "P":
main = main.convert("RGB")
for x in range(x_offset, main_size[0]):
for y in range(y_offset, main_size[1]):
pixel = main.getpixel((x, y))
truncated_pixel = trunc_pixel(pixel)
if prev_pixel_up == None or y == y_offset:
prev_pixel_up = truncated_pixel
else:
prev_pixel_up = trunc_pixel(main.getpixel((x, y-1)))
if prev_pixel_left == None or x == x_offset:
prev_pixel_left = truncated_pixel
else:
prev_pixel_left = trunc_pixel(main.getpixel((x-1, y)))
if truncated_pixel != prev_pixel_left:
shift_count = shift_count+1
if truncated_pixel != prev_pixel_up:
shift_count = shift_count+1
pixel_count = pixel_count+1
shifts = (float)(shift_count/2)/(float)(pixel_count) #Approximation of number of shifts, i.e. how chaotic the picture is
#The more jumbled the image under the watermark is, the more opaque the watermark will be.
new_alpha = min(0.8, 0.4+(((int)(shifts*10))/20.0))
wm_bands = list(watermark.split())
if len(wm_bands) == 4: #assumes alpha is last band
wm_bands[3] = wm_bands[3].point(lambda x: x*new_alpha) #Adjust opacity
watermark.putalpha(wm_bands[3])
# Paste the watermark (with alpha layer) at the bottom right and save it
main.paste(watermark, (x_offset, y_offset), watermark)
new_name = photo.replace(".", "_wm.")
main.save(new_name, "PNG")
print "Finished with %s" % photo
def trunc_pixel(pixel):
#Dividing each value by 25 approximates its color, i.e 250, 50, 55 is equal to 255, 57, 59. Change the 25 to increase or decrease precision
tpixel = ((math.floor(pixel[0]/25)), (math.floor(pixel[1]/25)), (math.floor(pixel[2]/25)))
return tpixel
def loopdirs(paths, wm):
for p in paths:
for fn in os.listdir(p):
fl = fn.lower()
if fl[-4:] == ".png" or fl[-4:] == ".jpg":
add_watermark(p+fn, wm)
if __name__ == '__main__':
dirs = [] #Each dir you want to iterate through
loopdirs(WATERMARK_LOCATION)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment