|
from PIL import Image, ImageDraw, ImageFont |
|
import os |
|
from typing import Dict, Any |
|
import cv2 |
|
import numpy as np |
|
import binascii |
|
from typing import Union |
|
import base64 |
|
import io |
|
|
|
def add_watermark(image_input: Union[str, Image.Image], watermark_text: str, opacity: float = 0.5) -> Union[str, Image.Image]: |
|
""" |
|
Add a semi-transparent text watermark to an image. |
|
|
|
Args: |
|
image_input: PIL Image object or base64 string |
|
watermark_text: The text to be used as watermark |
|
opacity: Opacity of the watermark (0.1 to 1.0) |
|
|
|
Returns: |
|
PIL Image object with watermark applied |
|
""" |
|
try: |
|
if isinstance(image_input, str): |
|
if image_input.startswith('data:image'): |
|
base64_data = image_input.split(',')[1] |
|
else: |
|
base64_data = image_input |
|
image_data = base64.b64decode(base64_data) |
|
image = Image.open(io.BytesIO(image_data)) |
|
else: |
|
image = image_input |
|
|
|
if image.mode != 'RGBA': |
|
image = image.convert('RGBA') |
|
|
|
overlay = Image.new('RGBA', image.size, (255, 255, 255, 0)) |
|
draw = ImageDraw.Draw(overlay) |
|
|
|
try: |
|
font_size = min(image.width, image.height) // 20 |
|
font = ImageFont.truetype("arial.ttf", font_size) |
|
except: |
|
try: |
|
font = ImageFont.load_default() |
|
except: |
|
font = ImageFont.load_default() |
|
|
|
bbox = draw.textbbox((0, 0), watermark_text, font=font) |
|
text_width = bbox[2] - bbox[0] |
|
text_height = bbox[3] - bbox[1] |
|
|
|
x = (image.width - text_width) // 2 |
|
y = (image.height - text_height) // 2 |
|
|
|
alpha_value = int(255 * opacity) |
|
text_color = (255, 255, 255, alpha_value) |
|
shadow_color = (0, 0, 0, int(alpha_value * 0.5)) |
|
|
|
draw.text((x-2, y-2), watermark_text, fill=shadow_color, font=font) |
|
draw.text((x, y), watermark_text, fill=text_color, font=font) |
|
|
|
watermarked = Image.alpha_composite(image, overlay) |
|
final_image = watermarked.convert('RGB') |
|
|
|
return final_image |
|
|
|
except Exception as e: |
|
print(f"Error adding watermark: {e}") |
|
return image_input if isinstance(image_input, Image.Image) else None |
|
|
|
def remove_watermark(image_input: Union[str, Image.Image], alpha: float = 2.0, beta: float = -160) -> Union[str, Image.Image]: |
|
try: |
|
if isinstance(image_input, str): |
|
if image_input.startswith('data:image'): |
|
base64_data = image_input.split(',')[1] |
|
else: |
|
base64_data = image_input |
|
image_data = base64.b64decode(base64_data) |
|
image = Image.open(io.BytesIO(image_data)) |
|
else: |
|
image = image_input |
|
|
|
img_array = np.array(image) |
|
|
|
new = alpha * img_array + beta |
|
new = np.clip(new, 0, 255).astype(np.uint8) |
|
|
|
result_image = Image.fromarray(new) |
|
|
|
return result_image |
|
|
|
except Exception as e: |
|
print(f"Error removing watermark: {e}") |
|
return image_input if isinstance(image_input, Image.Image) else None |