Spaces:
Running
Running
| import gradio as gr | |
| import threading | |
| import os | |
| import shutil | |
| import tempfile | |
| import time | |
| from util import process_image_edit, OPENROUTER_API_KEY | |
| # Configuration parameters for watermark removal | |
| FREE_TRY_N = 15 # Free phase: first 8 tries without restrictions | |
| SLOW_TRY_N = 20 # Slow phase start: 20 tries | |
| RATE_LIMIT_20 = 25 # Full restriction: blocked after 20 tries | |
| # Time window configuration (minutes) | |
| PHASE_1_WINDOW = 5 # 8-20 tries: 5 minutes | |
| MAX_IMAGES_PER_WINDOW = 2 # Max images per time window | |
| IP_Dict = {} | |
| # IP generation statistics and time window tracking | |
| IP_Generation_Count = {} # Record total generation count for each IP | |
| IP_Rate_Limit_Track = {} # Record generation count and timestamp in current time window for each IP | |
| def get_ip_generation_count(client_ip): | |
| """ | |
| Get IP generation count | |
| """ | |
| if client_ip not in IP_Generation_Count: | |
| IP_Generation_Count[client_ip] = 0 | |
| return IP_Generation_Count[client_ip] | |
| def increment_ip_generation_count(client_ip): | |
| """ | |
| Increment IP generation count | |
| """ | |
| if client_ip not in IP_Generation_Count: | |
| IP_Generation_Count[client_ip] = 0 | |
| IP_Generation_Count[client_ip] += 1 | |
| return IP_Generation_Count[client_ip] | |
| def get_ip_phase(client_ip): | |
| """ | |
| Get current phase for IP | |
| Returns: | |
| str: 'free', 'rate_limit_1', 'blocked' | |
| """ | |
| count = get_ip_generation_count(client_ip) | |
| if count < FREE_TRY_N: # 0-7 tries | |
| return 'free' | |
| elif count < SLOW_TRY_N: # 8-19 tries | |
| return 'rate_limit_1' # 5 minutes 2 images | |
| else: # 20+ tries | |
| return 'blocked' # Generation blocked | |
| def check_rate_limit_for_phase(client_ip, phase): | |
| """ | |
| Check rate limit for specific phase | |
| Returns: | |
| tuple: (is_limited, wait_time_minutes, current_count) | |
| """ | |
| if phase not in ['rate_limit_1']: | |
| return False, 0, 0 | |
| # Determine time window | |
| window_minutes = PHASE_1_WINDOW # 5 minutes | |
| current_time = time.time() | |
| window_key = f"{client_ip}_{phase}" | |
| # Clean expired records | |
| if window_key in IP_Rate_Limit_Track: | |
| track_data = IP_Rate_Limit_Track[window_key] | |
| # Check if within current time window | |
| if current_time - track_data['start_time'] > window_minutes * 60: | |
| # Time window expired, reset | |
| IP_Rate_Limit_Track[window_key] = { | |
| 'count': 0, | |
| 'start_time': current_time, | |
| 'last_generation': current_time | |
| } | |
| else: | |
| # Initialize | |
| IP_Rate_Limit_Track[window_key] = { | |
| 'count': 0, | |
| 'start_time': current_time, | |
| 'last_generation': current_time | |
| } | |
| track_data = IP_Rate_Limit_Track[window_key] | |
| # Check if exceeded limit | |
| if track_data['count'] >= MAX_IMAGES_PER_WINDOW: | |
| # Calculate remaining wait time | |
| elapsed = current_time - track_data['start_time'] | |
| wait_time = (window_minutes * 60) - elapsed | |
| wait_minutes = max(0, wait_time / 60) | |
| return True, wait_minutes, track_data['count'] | |
| return False, 0, track_data['count'] | |
| def record_generation_attempt(client_ip, phase): | |
| """ | |
| Record generation attempt | |
| """ | |
| # Increment total count | |
| increment_ip_generation_count(client_ip) | |
| # Record time window count | |
| if phase in ['rate_limit_1']: | |
| window_key = f"{client_ip}_{phase}" | |
| current_time = time.time() | |
| if window_key in IP_Rate_Limit_Track: | |
| IP_Rate_Limit_Track[window_key]['count'] += 1 | |
| IP_Rate_Limit_Track[window_key]['last_generation'] = current_time | |
| else: | |
| IP_Rate_Limit_Track[window_key] = { | |
| 'count': 1, | |
| 'start_time': current_time, | |
| 'last_generation': current_time | |
| } | |
| # Load sample images from samples directory | |
| def load_sample_images(): | |
| """Load sample images from samples directory""" | |
| samples_dir = "samples" | |
| sample_images = [] | |
| if os.path.exists(samples_dir): | |
| for filename in os.listdir(samples_dir): | |
| if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')): | |
| if "rm" in filename: continue | |
| file_path = os.path.join(samples_dir, filename) | |
| sample_images.append((file_path, filename)) | |
| return sample_images | |
| # Pre-processed results for sample images (local files) | |
| SAMPLE_RESULTS = { | |
| "sample01.jpeg": "samples/sample01_rm.jpeg", | |
| "sample02.jpeg": "samples/sample02_rm.jpeg", | |
| "1.jpg": "samples/1_rm.jpg", | |
| "4.jpg": "samples/4_rm.jpg", | |
| "10.jpg": "samples/10_rm.jpg" | |
| } | |
| def generate_smart_watermark_prompt(image_url): | |
| """Generate smart watermark removal prompt using OpenRouter API""" | |
| import requests | |
| import json | |
| try: | |
| api_key = OPENROUTER_API_KEY if 'OPENROUTER_API_KEY' in globals() else "" | |
| if not api_key: | |
| print("Warning: OPENROUTER_API_KEY not found") | |
| return "remove watermark in the image" | |
| headers = { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': f'Bearer {api_key}' | |
| } | |
| data = { | |
| "model": "google/gemini-2.5-flash-lite", | |
| "messages": [ | |
| {"role": "user", "content": "็ฐๅจ็จๆท่พๅ ฅไบไธๅผ ๅธฆๆฐดๅฐ็ๅพ็๏ผ้่ฆ็ๆไฟฎๅคpromptๆฅๅผๅฏผๅพๅ็ๆๆจกๅๅป้คๆฐดๅฐใไฝ ้่ฆๆพๅฐๆฐดๅฐ๏ผ็ถๅ่พๅบๅป้คๆฐดๅฐ็่ฑๆprompt๏ผๆๅบๆฐดๅฐ็ไฝ็ฝฎๅ็น็น๏ผ่ฎฉๆจกๅ็ฅ้ๅณๅฏ๏ผๅฐฝ้็ฎ็ญใ็ดๆฅ่พๅบpromptๅณๅฏใไธพไพ1: 'Remove the blue watermark in the lower right corner of the document'. ไธพไพ2: 'Remove the white watermark over the whole picture'"}, | |
| {"role": "assistant", "content": "ๅฅฝ็"}, | |
| { | |
| "role": "user", | |
| "content": [ | |
| {"type": "text", "text": "Generate an English prompt to remove the watermark in this image."}, | |
| {"type": "image_url", "image_url": {"url": image_url}} | |
| ] | |
| } | |
| ] | |
| } | |
| response = requests.post( | |
| 'https://openrouter.ai/api/v1/chat/completions', | |
| headers=headers, | |
| json=data, | |
| timeout=30 | |
| ) | |
| if response.status_code == 200: | |
| result = response.json() | |
| if result.get("choices") and len(result["choices"]) > 0: | |
| prompt = result["choices"][0]["message"]["content"].strip() | |
| print(f"โ Generated smart prompt: {prompt}") | |
| return prompt | |
| print(f"โ ๏ธ OpenRouter API failed with status {response.status_code}") | |
| return "remove watermark in the image" | |
| except Exception as e: | |
| print(f"โ ๏ธ Error generating smart prompt: {e}") | |
| return "remove watermark in the image" | |
| def remove_watermark_interface(input_image, force_removal, request: gr.Request, progress=gr.Progress()): | |
| """ | |
| Interface function for watermark removal with phase-based limitations | |
| """ | |
| try: | |
| # Extract user IP | |
| client_ip = request.client.host | |
| x_forwarded_for = dict(request.headers).get('x-forwarded-for') | |
| if x_forwarded_for: | |
| client_ip = x_forwarded_for | |
| if client_ip not in IP_Dict: | |
| IP_Dict[client_ip] = 0 | |
| IP_Dict[client_ip] += 1 | |
| if input_image is None: | |
| return None, "Please upload an image first", gr.update(visible=False) | |
| # Set initial prompt for watermark removal | |
| prompt = "remove watermark in the image" | |
| except Exception as e: | |
| print(f"โ ๏ธ Request preprocessing error: {e}") | |
| return None, "โ Request processing error", gr.update(visible=False) | |
| # Get user current phase | |
| current_phase = get_ip_phase(client_ip) | |
| current_count = get_ip_generation_count(client_ip) | |
| print(f"๐ User phase info - IP: {client_ip}, current phase: {current_phase}, generation count: {current_count}") | |
| # Check if completely blocked | |
| if current_phase == 'blocked': | |
| # Generate blocked limit button | |
| blocked_button_html = f""" | |
| <div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'> | |
| <a href='https://omnicreator.net/remove-watermark#generator' target='_blank' style=' | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 16px 32px; | |
| background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 12px; | |
| font-weight: 600; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 200px; | |
| box-shadow: 0 4px 15px rgba(231, 76, 60, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| '>๐ Remove More Watermarks</a> | |
| </div> | |
| """ | |
| return None, f"โ You have reached Hugging Face's free watermark removal limit. Please visit https://omnicreator.net/remove-watermark#generator for unlimited removal", gr.update(value=blocked_button_html, visible=True) | |
| # Check rate limit (applies to rate_limit phases) | |
| if current_phase in ['rate_limit_1']: | |
| is_limited, wait_minutes, window_count = check_rate_limit_for_phase(client_ip, current_phase) | |
| if is_limited: | |
| wait_minutes_int = int(wait_minutes) + 1 | |
| # Generate rate limit button | |
| rate_limit_button_html = f""" | |
| <div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'> | |
| <a href='https://omnicreator.net/remove-watermark#generator' target='_blank' style=' | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 16px 32px; | |
| background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 12px; | |
| font-weight: 600; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 200px; | |
| box-shadow: 0 4px 15px rgba(243, 156, 18, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| '>โฐ Skip Wait - Unlimited Watermark Removal</a> | |
| </div> | |
| """ | |
| return None, f"โ You have reached Hugging Face's free watermark removal limit. Please visit https://omnicreator.net/remove-watermark#generator for unlimited removal, or wait {wait_minutes_int} minutes before generating again", gr.update(value=rate_limit_button_html, visible=True) | |
| # No NSFW detection needed for watermark removal | |
| result_url = None | |
| status_message = "" | |
| def progress_callback(message): | |
| try: | |
| nonlocal status_message | |
| status_message = message | |
| # Add error handling to prevent progress update failure | |
| if progress is not None: | |
| progress(0.5, desc=message) | |
| except Exception as e: | |
| print(f"โ ๏ธ Progress update failed: {e}") | |
| try: | |
| # Record generation attempt (before actual generation to ensure correct count) | |
| record_generation_attempt(client_ip, current_phase) | |
| updated_count = get_ip_generation_count(client_ip) | |
| print(f"โ Processing started - IP: {client_ip}, phase: {current_phase}, total count: {updated_count}, prompt: {prompt.strip()}", flush=True) | |
| # Force removal mode: Generate smart prompt using OpenRouter API | |
| if force_removal: | |
| if progress is not None: | |
| progress(0.3, desc="๐ช AI Force Mode: Analyzing watermark pattern...") | |
| try: | |
| # Upload image to get URL for OpenRouter API | |
| from util import upload_user_img_r2 | |
| time_id = int(time.time()) | |
| image_url = upload_user_img_r2(client_ip, time_id, input_image) | |
| if image_url: | |
| # Generate smart prompt using OpenRouter API | |
| smart_prompt = generate_smart_watermark_prompt(image_url) | |
| if smart_prompt and smart_prompt.strip() != "remove watermark in the image": | |
| prompt = smart_prompt | |
| print(f"๐ Using AI Force Mode prompt: {prompt}") | |
| else: | |
| print("โ ๏ธ Using fallback prompt") | |
| else: | |
| print("โ ๏ธ Failed to upload image for AI analysis, using default prompt") | |
| except Exception as e: | |
| print(f"โ ๏ธ Force Mode prompt generation failed: {e}, using default prompt") | |
| if progress is not None: | |
| progress(0.5, desc="Starting force watermark removal...") | |
| # Call image editing processing function | |
| result_url, message, task_uuid = process_image_edit(input_image, prompt.strip(), progress_callback) | |
| if result_url: | |
| print(f"โ Watermark removal completed successfully - IP: {client_ip}, result_url: {result_url}, task_uuid: {task_uuid}", flush=True) | |
| # No NSFW detection needed for watermark removal | |
| final_result = result_url | |
| final_message = "โ " + message | |
| try: | |
| if progress is not None: | |
| progress(1.0, desc="Processing completed") | |
| except Exception as e: | |
| print(f"โ ๏ธ Final progress update failed: {e}") | |
| # Generate action buttons HTML like Trump AI Voice | |
| action_buttons_html = "" | |
| if task_uuid: | |
| task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" | |
| action_buttons_html = f""" | |
| <div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'> | |
| <a href='{task_detail_url}' target='_blank' style=' | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 16px 32px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 12px; | |
| font-weight: 600; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 160px; | |
| box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| '>๐ผ๏ธ Download HD Image</a> | |
| <a href='https://omnicreator.net/remove-watermark#generator' target='_blank' style=' | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 16px 32px; | |
| background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 12px; | |
| font-weight: 600; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 160px; | |
| box-shadow: 0 4px 15px rgba(17, 153, 142, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| '>๐ Remove More Watermarks</a> | |
| </div> | |
| <div style='text-align: center; margin: 15px 0; padding: 15px; background: linear-gradient(135deg, #fff5f5 0%, #fed7e2 100%); border-radius: 12px; border-left: 4px solid #f56565;'> | |
| <p style='margin: 0 0 10px 0; color: #4a5568; font-size: 14px; font-weight: 500;'> | |
| Not satisfied with the removal result? | |
| </p> | |
| <a href='https://omnicreator.net/remove-watermark' target='_blank' style=' | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 12px 24px; | |
| background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| font-size: 14px; | |
| text-align: center; | |
| box-shadow: 0 4px 12px rgba(245, 101, 101, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| '>๐ช Try Force Mode on Website</a> | |
| </div> | |
| """ | |
| return final_result, final_message, gr.update(value=action_buttons_html, visible=True) | |
| else: | |
| print(f"โ Processing failed - IP: {client_ip}, error: {message}", flush=True) | |
| return None, "โ " + message, gr.update(visible=False) | |
| except Exception as e: | |
| print(f"โ Processing exception - IP: {client_ip}, error: {str(e)}") | |
| return None, f"โ Error occurred during processing: {str(e)}", gr.update(visible=False) | |
| # Create Gradio interface | |
| def create_app(): | |
| with gr.Blocks( | |
| title="AI Watermark Remover", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .main-container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| .upload-area { | |
| border: 2px dashed #ccc; | |
| border-radius: 10px; | |
| padding: 20px; | |
| text-align: center; | |
| } | |
| .result-area { | |
| margin-top: 20px; | |
| padding: 20px; | |
| border-radius: 10px; | |
| background-color: #f8f9fa; | |
| } | |
| .use-as-input-btn { | |
| margin-top: 10px; | |
| width: 100%; | |
| } | |
| """, | |
| # Improve concurrency performance configuration | |
| head=""" | |
| <script> | |
| // Reduce client-side state update frequency, avoid excessive SSE connections | |
| if (window.gradio) { | |
| window.gradio.update_frequency = 2000; // Update every 2 seconds | |
| } | |
| </script> | |
| """ | |
| ) as app: | |
| # Main title - styled for watermark removal | |
| gr.HTML(""" | |
| <div style="text-align: center; margin: 5px auto 0px auto; max-width: 800px;"> | |
| <h1 style="color: #2c3e50; margin: 0; font-size: 3.5em; font-weight: 800; letter-spacing: 3px; text-shadow: 2px 2px 4px rgba(0,0,0,0.1);"> | |
| ๐งฝAI Watermark Remover | |
| </h1> | |
| </div> | |
| """, padding=False) | |
| # Powered by line below title - styled like Trump AI Voice | |
| gr.HTML(""" | |
| <div style="text-align: center; margin: 0px auto -5px auto;"> | |
| <p style="margin: 0; font-size: 16px; color: #999; font-weight: 400;"> | |
| powered by <a href="https://omnicreator.net/remove-watermark#generator" target="_blank" style="color: #667eea; text-decoration: none;">omnicreator.net</a> | |
| </p> | |
| </div> | |
| """, padding=False) | |
| # Load sample images | |
| sample_images = load_sample_images() | |
| # Watermark removal interface (New 2-column layout) | |
| with gr.Row(): | |
| # --- LEFT COLUMN (INPUT & CONTROLS) --- | |
| with gr.Column(scale=1): | |
| gr.Markdown("### ๐ธ Upload Image with Watermark") | |
| input_image = gr.Image( | |
| label="Select image to remove watermark", | |
| type="pil", | |
| height=450, | |
| elem_classes=["upload-area"] | |
| ) | |
| force_removal = gr.Checkbox( | |
| label="๐ช Force Removal", | |
| info="Ultimate AI-powered watermark removal. AI analyzes the watermark for better results.", | |
| value=False | |
| ) | |
| remove_button = gr.Button( | |
| "๐งฝRemove Watermark", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| # --- RIGHT COLUMN (OUTPUT) --- | |
| with gr.Column(scale=1): | |
| gr.Markdown("### ๐ฏ Watermark Removal Result") | |
| output_image = gr.Image( | |
| label="Image without watermark", | |
| height=450, | |
| elem_classes=["result-area"] | |
| ) | |
| use_as_input_btn = gr.Button( | |
| "๐ Use as Input", | |
| variant="secondary", | |
| size="sm", | |
| elem_classes=["use-as-input-btn"] | |
| ) | |
| status_output = gr.Textbox( | |
| label="Processing status", | |
| lines=2, | |
| max_lines=3, | |
| interactive=False | |
| ) | |
| action_buttons = gr.HTML(visible=False) | |
| # Sample images gallery (moved below main interface) | |
| sample_buttons = [] | |
| if sample_images: | |
| gr.Markdown("### ๐ก Try with Sample Images") | |
| with gr.Row(): | |
| for idx, (img_path, img_name) in enumerate(sample_images[:4]): # Show first 4 samples | |
| with gr.Column(scale=1): | |
| sample_img = gr.Image( | |
| value=img_path, | |
| label=img_name, | |
| height=150, | |
| interactive=False | |
| ) | |
| use_sample_btn = gr.Button( | |
| f"Use {img_name}", | |
| size="sm", | |
| variant="secondary" | |
| ) | |
| sample_buttons.append((use_sample_btn, img_path)) | |
| # Add sample image button functionality with demo processing | |
| def create_sample_handler(img_path, img_name): | |
| def handler(): | |
| import time | |
| import os | |
| from PIL import Image | |
| # Wait 3 seconds as requested | |
| time.sleep(3) | |
| # Get the pre-processed result file path | |
| result_file_path = SAMPLE_RESULTS.get(img_name) | |
| if result_file_path and os.path.exists(result_file_path): | |
| # Load the result image from local file | |
| try: | |
| result_image = Image.open(result_file_path) | |
| return img_path, result_image, "โ sample watermark removal completed! This is a demo result." | |
| except Exception as e: | |
| print(f"Failed to load sample result from {result_file_path}: {e}") | |
| # Fallback: just return the input image | |
| return img_path, None, "โ sample image loaded. Click 'Remove Watermark' to process." | |
| return handler | |
| for sample_btn, img_path in sample_buttons: | |
| img_name = os.path.basename(img_path) | |
| sample_btn.click( | |
| fn=create_sample_handler(img_path, img_name), | |
| outputs=[input_image, output_image, status_output], | |
| show_progress=True | |
| ) | |
| # Bind button click events | |
| remove_button.click( | |
| fn=remove_watermark_interface, | |
| inputs=[input_image, force_removal], | |
| outputs=[output_image, status_output, action_buttons], | |
| show_progress=True, | |
| concurrency_limit=10, | |
| api_name="remove_watermark" | |
| ) | |
| # "Use as Input" button functionality | |
| def simple_use_as_input(output_img): | |
| if output_img is not None: | |
| return output_img | |
| return None | |
| use_as_input_btn.click( | |
| fn=simple_use_as_input, | |
| inputs=[output_image], | |
| outputs=[input_image] | |
| ) | |
| # Watermark Removal SEO Content Section | |
| gr.HTML(""" | |
| <div style="width: 100%; margin: 50px 0; padding: 0 20px;"> | |
| <div style="text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; border-radius: 20px; margin: 40px 0;"> | |
| <h2 style="margin: 0 0 20px 0; font-size: 2.2em; font-weight: 700;"> | |
| ๐งฝUnlimited AI Watermark Removal | |
| </h2> | |
| <p style="margin: 0 0 25px 0; font-size: 1.2em; opacity: 0.95; line-height: 1.6;"> | |
| Remove watermarks from any image instantly with advanced AI technology! Clean your photos and documents | |
| without compromising image quality using our professional watermark removal tool. | |
| </p> | |
| <div style="display: flex; justify-content: center; gap: 25px; flex-wrap: wrap; margin: 30px 0;"> | |
| <a href="https://omnicreator.net/remove-watermark#generator" target="_blank" style=" | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 20px 40px; | |
| background: linear-gradient(135deg, #ff6b6b 0%, #feca57 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 15px; | |
| font-weight: 700; | |
| font-size: 18px; | |
| text-align: center; | |
| min-width: 250px; | |
| box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| transform: scale(1); | |
| " onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'"> | |
| ๐งฝGet Unlimited Watermark Removal | |
| </a> | |
| </div> | |
| <p style="color: rgba(255,255,255,0.9); font-size: 1em; margin: 20px 0 0 0;"> | |
| Join thousands of users who trust Omni Creator for professional watermark removal! | |
| </p> | |
| </div> | |
| <div style="text-align: center; margin: 25px auto; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); padding: 35px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1);"> | |
| <h2 style="color: #2c3e50; margin: 0 0 20px 0; font-size: 1.9em; font-weight: 700;"> | |
| ๐ Professional AI Watermark Remover - Fast & Accurate | |
| </h2> | |
| <p style="color: #555; font-size: 1.1em; line-height: 1.6; margin: 0 0 20px 0; padding: 0 20px;"> | |
| Clean your images effortlessly with our advanced AI watermark removal technology. Whether you're dealing with | |
| text watermarks, logo stamps, or transparent overlays - our intelligent algorithm removes them while preserving | |
| the original image quality and details. | |
| </p> | |
| </div> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 25px; margin: 40px 0;"> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #e74c3c;"> | |
| <h3 style="color: #e74c3c; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| ๐ฏ Unlimited Removal | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| Premium users enjoy unlimited watermark removal without daily limits or processing restrictions. | |
| Clean as many images as you need, whenever you need them, with no quality loss. | |
| </p> | |
| </div> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #3498db;"> | |
| <h3 style="color: #3498db; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| ๐ฏ Smart Detection | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| AI automatically identifies and removes various types of watermarks including text, logos, stamps, and | |
| transparent overlays without affecting the main image content. | |
| </p> | |
| </div> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #27ae60;"> | |
| <h3 style="color: #27ae60; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| โก Lightning Fast Processing | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| Advanced AI infrastructure delivers watermark-free results in seconds. No waiting in queues, | |
| no processing delays - just instant, professional-grade watermark removal. | |
| </p> | |
| </div> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #9b59b6;"> | |
| <h3 style="color: #9b59b6; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| ๐จ Quality Preservation | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| Intelligent inpainting technology reconstructs watermark areas seamlessly while maintaining original | |
| image quality, colors, textures, and details perfectly. | |
| </p> | |
| </div> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #f39c12;"> | |
| <h3 style="color: #f39c12; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| ๐ Premium Quality | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| State-of-the-art AI models trained specifically for watermark removal deliver exceptional results. | |
| Professional quality output suitable for commercial use and high-end projects. | |
| </p> | |
| </div> | |
| <div style="background: white; padding: 30px; border-radius: 15px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); border-left: 5px solid #34495e;"> | |
| <h3 style="color: #34495e; margin: 0 0 15px 0; font-size: 1.4em; font-weight: 600;"> | |
| ๐ Universal Compatibility | |
| </h3> | |
| <p style="color: #666; margin: 0; line-height: 1.6; font-size: 1em;"> | |
| Works with all image formats (JPG, PNG, GIF, BMP) and removes any type of watermark. From photos to | |
| documents, product images to artwork - we clean them all perfectly. | |
| </p> | |
| </div> | |
| </div> | |
| <div style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); color: white; padding: 40px; border-radius: 20px; margin: 40px 0; text-align: center;"> | |
| <h2 style="margin: 0 0 25px 0; font-size: 1.8em; font-weight: 700;"> | |
| ๐ Why Choose Premium Watermark Removal? | |
| </h2> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin: 30px 0;"> | |
| <div style="background: rgba(255,255,255,0.15); padding: 20px; border-radius: 12px;"> | |
| <h4 style="margin: 0 0 10px 0; font-size: 1.2em;">๐ซ No Processing Limits</h4> | |
| <p style="margin: 0; opacity: 0.9; font-size: 0.95em;">Remove watermarks from unlimited images without waiting periods or daily restrictions</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 20px; border-radius: 12px;"> | |
| <h4 style="margin: 0 0 10px 0; font-size: 1.2em;">๐งฝAdvanced Removal</h4> | |
| <p style="margin: 0; opacity: 0.9; font-size: 0.95em;">Remove any type of watermark including complex, transparent, and multi-layered marks</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 20px; border-radius: 12px;"> | |
| <h4 style="margin: 0 0 10px 0; font-size: 1.2em;">โก Priority Processing</h4> | |
| <p style="margin: 0; opacity: 0.9; font-size: 0.95em;">Skip queues and get instant watermark removal with dedicated processing power</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 20px; border-radius: 12px;"> | |
| <h4 style="margin: 0 0 10px 0; font-size: 1.2em;">๐จ Perfect Quality</h4> | |
| <p style="margin: 0; opacity: 0.9; font-size: 0.95em;">Access to latest AI models for highest quality watermark removal results</p> | |
| </div> | |
| </div> | |
| <div style="display: flex; justify-content: center; margin: 25px 0 0 0;"> | |
| <a href="https://omnicreator.net/remove-watermark#generator" target="_blank" style=" | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 18px 35px; | |
| background: rgba(255,255,255,0.9); | |
| color: #333; | |
| text-decoration: none; | |
| border-radius: 15px; | |
| font-weight: 700; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 200px; | |
| box-shadow: 0 6px 20px rgba(0,0,0,0.3); | |
| transition: all 0.3s ease; | |
| border: none; | |
| ">๐ Start Creating Now</a> | |
| </div> | |
| </div> | |
| <div style="background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%); padding: 30px; border-radius: 15px; margin: 40px 0;"> | |
| <h3 style="color: #8b5cf6; text-align: center; margin: 0 0 25px 0; font-size: 1.5em; font-weight: 700;"> | |
| ๐ก Pro Tips for Best Watermark Removal | |
| </h3> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px;"> | |
| <div style="background: rgba(255,255,255,0.85); padding: 18px; border-radius: 12px;"> | |
| <strong style="color: #8b5cf6; font-size: 1.1em;">๐ Image Quality:</strong> | |
| <p style="color: #555; margin: 5px 0 0 0; line-height: 1.5;">Higher resolution input images (up to 10MB) generally produce better watermark removal results and finer details.</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.85); padding: 18px; border-radius: 12px;"> | |
| <strong style="color: #8b5cf6; font-size: 1.1em;">๐ฏ Clean Images:</strong> | |
| <p style="color: #555; margin: 5px 0 0 0; line-height: 1.5;">Images with simple backgrounds work best. Complex patterns behind watermarks may require multiple processing attempts.</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.85); padding: 18px; border-radius: 12px;"> | |
| <strong style="color: #8b5cf6; font-size: 1.1em;">โก Iterative Process:</strong> | |
| <p style="color: #555; margin: 5px 0 0 0; line-height: 1.5;">Use "Use as Input" feature to refine results. Multiple iterations can remove stubborn or complex watermarks completely.</p> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.85); padding: 18px; border-radius: 12px;"> | |
| <strong style="color: #8b5cf6; font-size: 1.1em;">๐ผ๏ธ File Formats:</strong> | |
| <p style="color: #555; margin: 5px 0 0 0; line-height: 1.5;">JPG and PNG formats work best. Avoid heavily compressed images as they may affect watermark detection accuracy.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div style="text-align: center; margin: 25px auto; background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); padding: 35px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1);"> | |
| <h2 style="color: #2c3e50; margin: 0 0 20px 0; font-size: 1.8em; font-weight: 700;"> | |
| ๐ Perfect For Every Watermark Removal Need | |
| </h2> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 25px 0; text-align: left;"> | |
| <div style="background: rgba(255,255,255,0.8); padding: 20px; border-radius: 12px;"> | |
| <h4 style="color: #e74c3c; margin: 0 0 10px 0;">๐ Documents</h4> | |
| <ul style="color: #555; margin: 0; padding-left: 18px; line-height: 1.6;"> | |
| <li>PDFs with watermarks</li> | |
| <li>Scanned documents</li> | |
| <li>Legal papers</li> | |
| <li>Certificates</li> | |
| </ul> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.8); padding: 20px; border-radius: 12px;"> | |
| <h4 style="color: #3498db; margin: 0 0 10px 0;">๐ธ Photography</h4> | |
| <ul style="color: #555; margin: 0; padding-left: 18px; line-height: 1.6;"> | |
| <li>Stock photos</li> | |
| <li>Portrait photos</li> | |
| <li>Event photography</li> | |
| <li>Nature images</li> | |
| </ul> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.8); padding: 20px; border-radius: 12px;"> | |
| <h4 style="color: #27ae60; margin: 0 0 10px 0;">๐๏ธ E-commerce</h4> | |
| <ul style="color: #555; margin: 0; padding-left: 18px; line-height: 1.6;"> | |
| <li>Product images</li> | |
| <li>Catalog photos</li> | |
| <li>Supplier images</li> | |
| <li>Brand cleanup</li> | |
| </ul> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.8); padding: 20px; border-radius: 12px;"> | |
| <h4 style="color: #9b59b6; margin: 0 0 10px 0;">๐ฑ Social Media</h4> | |
| <ul style="color: #555; margin: 0; padding-left: 18px; line-height: 1.6;"> | |
| <li>Content creation</li> | |
| <li>Profile pictures</li> | |
| <li>Marketing visuals</li> | |
| <li>Clean presentations</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div style="text-align: center; margin: 25px 0 0 0;"> | |
| <a href="https://omnicreator.net/remove-watermark#generator" target="_blank" style=" | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 18px 35px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 15px; | |
| font-weight: 700; | |
| font-size: 16px; | |
| text-align: center; | |
| min-width: 220px; | |
| box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4); | |
| transition: all 0.3s ease; | |
| border: none; | |
| ">๐งฝStart Removing Watermarks</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div style="text-align: center; margin: 30px auto 20px auto; padding: 20px;"> | |
| <p style="margin: 0 0 10px 0; font-size: 18px; color: #333; font-weight: 500;"> | |
| Powered by <a href="https://omnicreator.net/remove-watermark#generator" target="_blank" style="color: #667eea; text-decoration: none; font-weight: bold;">Omni Creator</a> | |
| </p> | |
| <p style="margin: 0; font-size: 14px; color: #999; font-weight: 400;"> | |
| The ultimate AI watermark removal platform โข Professional results, unlimited processing | |
| </p> | |
| </div> | |
| """, padding=False) | |
| return app | |
| if __name__ == "__main__": | |
| app = create_app() | |
| # Improve queue configuration to handle high concurrency and prevent SSE connection issues | |
| app.queue( | |
| default_concurrency_limit=20, # Default concurrency limit | |
| max_size=50, # Maximum queue size | |
| api_open=False # Close API access to reduce resource consumption | |
| ) | |
| app.launch( | |
| server_name="0.0.0.0", | |
| show_error=True, # Show detailed error information | |
| quiet=False, # Keep log output | |
| max_threads=40, # Increase thread pool size | |
| height=800, | |
| favicon_path=None # Reduce resource loading | |
| ) |