Spaces:
Sleeping
Sleeping
| """ | |
| Hugging Face Space: Image Watermarker | |
| Processes images to add subtle, non-removable watermarks. | |
| Requirements: pillow, requests | |
| """ | |
| import gradio as gr | |
| from PIL import Image, ImageDraw, ImageFont | |
| import io | |
| import os | |
| def apply_watermark(image, watermark_text, position="bottom-right", opacity=0.7): | |
| """ | |
| Apply a text watermark to an image. | |
| Args: | |
| image: PIL Image object | |
| watermark_text: Text to overlay | |
| position: One of 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'center' | |
| opacity: Float 0.0-1.0 | |
| Returns: | |
| PIL Image with watermark | |
| """ | |
| if image.mode != 'RGBA': | |
| image = image.convert('RGBA') | |
| # Create watermark layer | |
| watermark_layer = Image.new('RGBA', image.size, (255, 255, 255, 0)) | |
| draw = ImageDraw.Draw(watermark_layer) | |
| # Try to load a font, fall back to default | |
| try: | |
| # Try common font paths | |
| font_paths = [ | |
| "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", | |
| "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf", | |
| "C:\\Windows\\Fonts\\arial.ttf", | |
| "/System/Library/Fonts/Helvetica.ttc" | |
| ] | |
| font = None | |
| for path in font_paths: | |
| if os.path.exists(path): | |
| font = ImageFont.truetype(path, 36) | |
| break | |
| if font is None: | |
| font = ImageFont.load_default() | |
| except Exception: | |
| font = ImageFont.load_default() | |
| # Get text bounding box | |
| bbox = draw.textbbox((0, 0), watermark_text, font=font) | |
| text_width = bbox[2] - bbox[0] | |
| text_height = bbox[3] - bbox[1] | |
| # Calculate position | |
| padding = 20 | |
| img_width, img_height = image.size | |
| if position == "top-left": | |
| x, y = padding, padding | |
| elif position == "top-right": | |
| x, y = img_width - text_width - padding, padding | |
| elif position == "bottom-left": | |
| x, y = padding, img_height - text_height - padding | |
| elif position == "bottom-right": | |
| x, y = img_width - text_width - padding, img_height - text_height - padding | |
| elif position == "center": | |
| x, y = (img_width - text_width) // 2, (img_height - text_height) // 2 | |
| else: | |
| x, y = img_width - text_width - padding, img_height - text_height - padding | |
| # Draw text with opacity | |
| alpha = int(255 * opacity) | |
| draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, alpha)) | |
| # Composite | |
| watermarked = Image.alpha_composite(image, watermark_layer) | |
| return watermarked.convert('RGB') | |
| def process_image(input_image, watermark_text, position, opacity): | |
| if input_image is None: | |
| return None | |
| result = apply_watermark(input_image, watermark_text, position, float(opacity)) | |
| return result | |
| # Gradio Interface | |
| with gr.Blocks(title="MMahBot Watermarker") as demo: | |
| gr.Markdown("# 🛡️ MMahBot Smart Watermarker") | |
| gr.Markdown("Upload an image and add a subtle, professional watermark.") | |
| with gr.Row(): | |
| with gr.Column(): | |
| input_img = gr.Image(type="pil", label="Upload Image") | |
| watermark_text = gr.Textbox( | |
| label="Watermark Text", | |
| value="@mmahbot", | |
| placeholder="Enter watermark text" | |
| ) | |
| position = gr.Dropdown( | |
| choices=["bottom-right", "bottom-left", "top-right", "top-left", "center"], | |
| value="bottom-right", | |
| label="Position" | |
| ) | |
| opacity = gr.Slider( | |
| minimum=0.1, maximum=1.0, value=0.7, step=0.1, | |
| label="Opacity" | |
| ) | |
| submit_btn = gr.Button("Apply Watermark", variant="primary") | |
| with gr.Column(): | |
| output_img = gr.Image(type="pil", label="Watermarked Image") | |
| submit_btn.click( | |
| fn=process_image, | |
| inputs=[input_img, watermark_text, position, opacity], | |
| outputs=output_img | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |