manga / utils /watermark_utils.py
sayed555's picture
Upload 48 files
de2b10e verified
import os.path as osp
from PIL import Image
def apply_watermark_to_pil_image(img_pil: Image.Image, watermark_path: str, opacity: float = 0.7) -> Image.Image:
"""
Apply watermark to a PIL image
Args:
img_pil (Image.Image): Source PIL image
watermark_path (str): Path to watermark image
opacity (float): Watermark opacity (0.0 - 1.0)
Returns:
Image.Image: Watermarked PIL image
"""
if not osp.exists(watermark_path):
return img_pil
try:
watermark = Image.open(watermark_path)
except Exception:
return img_pil
# Ensure images are in RGBA mode
if img_pil.mode != 'RGBA':
img_pil = img_pil.convert('RGBA')
if watermark.mode != 'RGBA':
watermark = watermark.convert('RGBA')
# Fixed watermark size (adjust as needed)
WATERMARK_FIXED_WIDTH = 418
WATERMARK_FIXED_HEIGHT = 120
# Resize watermark
watermark = watermark.resize((WATERMARK_FIXED_WIDTH, WATERMARK_FIXED_HEIGHT), Image.LANCZOS)
# Apply opacity
if opacity < 1.0:
alpha = watermark.split()[3]
alpha = alpha.point(lambda p: p * opacity)
watermark.putalpha(alpha)
# Get image dimensions
img_width, img_height = img_pil.size
# Create transparent layer for watermarks
wm_layer = Image.new('RGBA', img_pil.size, (0, 0, 0, 0))
# Calculate watermark positions (bottom to top)
initial_y = img_height - watermark.height - 10 # 10px from bottom
x_position = 10 # 10px from left
# Repeat watermark vertically
current_y = initial_y
while current_y > -watermark.height:
if current_y < 0:
# Crop watermark if it goes beyond top boundary
crop_height = watermark.height + current_y
if crop_height > 0:
partial_wm = watermark.crop((0, -current_y, watermark.width, watermark.height))
wm_layer.paste(partial_wm, (x_position, 0), partial_wm)
else:
wm_layer.paste(watermark, (x_position, current_y), watermark)
current_y -= 8000 # Vertical spacing (adjust as needed)
# Composite original image with watermark layer
return Image.alpha_composite(img_pil, wm_layer)