76 lines
1.7 KiB
Python
76 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
from watermark.helper import adjust_marker_layer, set_opacity
|
|
|
|
logger = logging.getLogger("watermark.markers")
|
|
|
|
|
|
def text_marker(
|
|
font_or_path,
|
|
content,
|
|
size=20,
|
|
color="black",
|
|
rotation=0,
|
|
alpha: int | float = 1,
|
|
**kwargs,
|
|
):
|
|
|
|
# set font and get the font size which determined by content.
|
|
font = ImageFont.truetype(font_or_path, size=size)
|
|
CONTENT_SIZE = font.getsize(text=content)
|
|
|
|
layer = Image.new("RGBA", CONTENT_SIZE)
|
|
|
|
plot = ImageDraw.Draw(layer)
|
|
plot.text(
|
|
xy=(0, 0), # x=0, y=0
|
|
text=content,
|
|
fill=color,
|
|
font=font,
|
|
align="center",
|
|
)
|
|
if rotation:
|
|
layer = layer.rotate(rotation, expand=True)
|
|
|
|
if alpha:
|
|
layer = set_opacity(layer, alpha)
|
|
|
|
return layer
|
|
|
|
|
|
def image_marker(fpath, zoom=0.8, rotation=0, alpha: int | float = 1, **kwargs):
|
|
|
|
# convert image watermarker to RGBA mode.
|
|
layer = Image.open(fpath).convert("RGBA")
|
|
|
|
width, height = layer.size
|
|
|
|
if 0 <= zoom <= 1:
|
|
layer = layer.resize((int(width * zoom), int(height * zoom)))
|
|
|
|
if rotation:
|
|
layer = layer.rotate(rotation, expand=True)
|
|
|
|
if alpha:
|
|
layer = set_opacity(layer, alpha)
|
|
|
|
return layer
|
|
|
|
|
|
def make(path, *, text=None, image=None, **kwargs):
|
|
pic = Image.open(path).convert("RGBA")
|
|
if text and not image:
|
|
marker = text_marker(text, **kwargs)
|
|
elif not text and image:
|
|
marker = image_marker(image, **kwargs)
|
|
else:
|
|
raise ValueError("use text or image")
|
|
|
|
layer = adjust_marker_layer(pic, marker, **kwargs)
|
|
marked = Image.alpha_composite(pic, layer)
|
|
|
|
return marked
|