diff --git "a/__lib__/app.py" "b/__lib__/app.py" --- "a/__lib__/app.py" +++ "b/__lib__/app.py" @@ -9,7 +9,7 @@ import util from util import (process_image_edit, process_text_to_image, process_image_upscale, process_face_swap, process_multi_image_edit, process_watermark_removal, download_and_check_result_nsfw, GoodWebsiteUrl, RateLimitConfig, create_mask_from_layers, - TASK_LOCK_MINUTES, PRINT_STATS_INTERVAL) + TASK_LOCK_MINUTES, PRINT_STATS_INTERVAL, NSFW_BLUR_SECONDS) from nfsw import NSFWDetector @@ -18,30 +18,8 @@ rate_limit_config = RateLimitConfig() # ============================================================================= -# i18n 翻译系统 - Load from encrypted modules +# IP归属地判断 - 保留用于限速和统计 # ============================================================================= -import sys -from pathlib import Path - -# Add i18n module to path -_i18n_module_path = Path(__file__).parent / "__lib__" / "i18n" -if str(_i18n_module_path) not in sys.path: - sys.path.insert(0, str(_i18n_module_path)) - -# Import encrypted i18n loader -from i18n import translations as _translations -translations = _translations - -def load_translations(): - """Compatibility function - translations are already loaded""" - return translations - -def t(key, lang="en"): - default_en = translations.get("en", {}) - lang_dict = translations.get(lang) or default_en - if key in lang_dict: - return lang_dict[key] - return default_en.get(key, key) def has_active_task(client_ip): @@ -368,16 +346,36 @@ def check_nsfw_for_result(result_url, country, current_count): return False -def create_nsfw_blurred_response(result_url, redirect_url, lang): +def create_nsfw_blurred_response(result_url, redirect_url): """ - 创建NSFW模糊处理后的响应HTML + 创建NSFW模糊处理后的响应HTML - 使用CSS filter动画实现延迟模糊效果(时间由NSFW_BLUR_SECONDS配置) 返回: (result_html, action_html) 或 None 如果模糊失败 """ - blurred_image = apply_gaussian_blur_to_image_url(result_url) - if blurred_image is None: - return None + # 创建唯一ID + unique_id = f"nsfw_{int(time.time() * 1000)}" + + # 计算动画时间点(在总时长中的百分比) + # 前N秒保持清晰,然后在1秒内过渡到模糊 + total_duration = NSFW_BLUR_SECONDS + 1 + clear_percentage = (NSFW_BLUR_SECONDS / total_duration) * 100 + + # 使用CSS filter实现模糊效果,从清晰到模糊的动画 + result_html = f""" + +
+ Result Image +
+ """ - blurred_html = pil_image_to_base64_html(blurred_image) nsfw_button_html = f"""
🔒 Unlock Full Image - Visit Website
""" - return blurred_html, nsfw_button_html + return result_html, nsfw_button_html # ============================================================================= @@ -544,11 +542,11 @@ def pil_image_to_base64_html(pil_image, max_height=500): return "" -def create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, lang, show_like_tip): +def create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, is_restricted, show_like_tip): """创建操作按钮HTML""" action_buttons_html = "" - if task_uuid and lang not in ["zh", "hi", "ru"]: + if task_uuid and not is_restricted: task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" from urllib.parse import quote encoded_prompt = quote(prompt.strip()) if prompt else "" @@ -612,7 +610,7 @@ def create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, l """ - if show_like_tip or lang in ["zh", "hi", "ru"]: + if show_like_tip or is_restricted: action_buttons_html += create_like_tip_html() return action_buttons_html @@ -621,7 +619,7 @@ def create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, l # ============================================================================= # 单图编辑接口 # ============================================================================= -def edit_image_interface(input_image, prompt, lang, request: gr.Request, progress=gr.Progress()): +def edit_image_interface(input_image, prompt, request: gr.Request, progress=gr.Progress()): """单图编辑接口""" try: client_ip = request.client.host @@ -633,15 +631,15 @@ def edit_image_interface(input_image, prompt, lang, request: gr.Request, progres util.IP_Dict[client_ip] += 1 if input_image is None: - return "", None, t("error_upload_first", lang), gr.update(visible=False) + return "", None, "❌ Please upload an image first", gr.update(visible=False) if not prompt or prompt.strip() == "": - return "", None, t("error_enter_prompt", lang), gr.update(visible=False) + return "", None, "❌ Please enter editing instructions", gr.update(visible=False) if len(prompt.strip()) <= 3: - return "", None, t("error_prompt_too_short", lang), gr.update(visible=False) + return "", None, "❌ Prompt is too short. Please provide detailed editing instructions.", gr.update(visible=False) except Exception as e: - return "", None, t("error_request_processing", lang), gr.update(visible=False) + return "", None, "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") @@ -650,7 +648,7 @@ def edit_image_interface(input_image, prompt, lang, request: gr.Request, progres is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查是否有活动任务(3分钟内) is_active, remaining_seconds = has_active_task(client_ip) @@ -659,14 +657,14 @@ def edit_image_interface(input_image, prompt, lang, request: gr.Request, progres # 检查是否被封锁 if current_phase == 'blocked': - return "", None, t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", None, "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) # 检查速率限制 if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: 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 - return "", None, t("error_free_limit_wait", lang).format(wait_minutes_int=wait_minutes_int), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", None, f"⏰ Rate limit reached. Please wait {wait_minutes_int} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # NSFW检测 is_nsfw_task, _ = check_nsfw_for_input(input_image, country, current_count, client_ip) @@ -689,16 +687,19 @@ def edit_image_interface(input_image, prompt, lang, request: gr.Request, progres # 设置任务锁定 set_active_task(client_ip, True) - task_priority = 1 if current_count < rate_limit_config.HIGH_PRIORITY_COUNT else 0 + # 判断是否使用高速高清模式 + use_high_speed_mode = current_count < rate_limit_config.HIGH_SPEED_HD_COUNT + task_priority = 1 if use_high_speed_mode else 0 record_generation_attempt(client_ip, current_phase) updated_count = get_ip_generation_count(client_ip) - print(f"✅ [Single Edit] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Priority: {task_priority}, Prompt: {prompt.strip()[:50]}...", flush=True) + mode_info = "High-Speed HD" if use_high_speed_mode else "Standard" + print(f"✅ [Single Edit] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Mode: {mode_info}, Prompt: {prompt.strip()[:50]}...", flush=True) input_image_url, result_url, message, task_uuid = process_image_edit(input_image, prompt.strip(), None, progress_callback, priority=task_priority, client_ip=client_ip) if message and message.startswith("HF_LIMIT_EXCEEDED:"): - return "", None, t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", None, "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -707,34 +708,41 @@ def edit_image_interface(input_image, prompt, lang, request: gr.Request, progres # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) # 解锁任务 # 返回None作为URL,防止用户通过"Use as Input"绕过NSFW检测 - return blurred_html, None, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, None, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) # 正常情况:返回HTML显示图片 result_html = create_result_image_html(result_url) - action_html = create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, lang, show_like_tip) + action_html = create_action_buttons_html(task_uuid, input_image_url, result_url, prompt, is_restricted, show_like_tip) set_active_task(client_ip, False) # 解锁任务 print(f"✅ [Single Edit] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) - return result_html, result_url, t("status_completed_message", lang).format(message=message), gr.update(value=action_html, visible=True) + + # 添加模式提示 + if use_high_speed_mode: + status_msg = f"✅ Completed with High-Speed HD Mode: {message}" + else: + status_msg = f"✅ Completed with Standard Mode: {message}\n💡 Visit https://omnicreator.net for High-Speed HD generation" + + return result_html, result_url, status_msg, gr.update(value=action_html, visible=True) else: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Single Edit] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", None, t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", None, f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Single Edit] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", None, t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", None, f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= # 多图编辑接口 # ============================================================================= -def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, aspect_ratio, lang, request: gr.Request, progress=gr.Progress()): +def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, aspect_ratio, request: gr.Request, progress=gr.Progress()): """多图编辑接口""" try: client_ip = request.client.host @@ -745,24 +753,25 @@ def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, images = [img for img in [input_image1, input_image2, input_image3] if img is not None] if len(images) < 2: - return "", t("error_multi_image_required", lang), gr.update(visible=False) + return "", "❌ Please upload at least 2 images", gr.update(visible=False) if not prompt or prompt.strip() == "": - return "", t("error_enter_prompt", lang), gr.update(visible=False) + return "", "❌ Please enter editing instructions", gr.update(visible=False) if len(prompt.strip()) <= 3: - return "", t("error_prompt_too_short", lang), gr.update(visible=False) + return "", "❌ Prompt is too short. Please provide detailed editing instructions.", gr.update(visible=False) except Exception as e: - return "", t("error_request_processing", lang), gr.update(visible=False) + return "", "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") country_config = rate_limit_config.get_country_config(country) current_phase = get_ip_phase(client_ip) current_count = get_ip_generation_count(client_ip) + is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查是否有活动任务(3分钟内) is_active, remaining_seconds = has_active_task(client_ip) @@ -775,13 +784,13 @@ def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, # ��查是否被封锁 if current_phase == 'blocked': - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: is_limited, wait_minutes, _ = check_rate_limit_for_phase(client_ip, current_phase) if is_limited: wait_minutes_int = int(wait_minutes) + 1 - return "", t("error_free_limit_wait", lang).format(wait_minutes_int=wait_minutes_int), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", f"⏰ Rate limit reached. Please wait {wait_minutes_int} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # NSFW检测 - 检测所有输入图片 is_nsfw_task = False @@ -822,7 +831,7 @@ def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, if message and message.startswith("HF_LIMIT_EXCEEDED:"): set_active_task(client_ip, False) # 解锁任务 - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -831,21 +840,21 @@ def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) - return blurred_html, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) result_html = create_result_image_html(result_url) - action_html = create_action_buttons_html(task_uuid, input_url, result_url, prompt, lang, show_like_tip) + action_html = create_action_buttons_html(task_uuid, input_url, result_url, prompt, is_restricted, show_like_tip) # 添加模式提示信息 if use_high_speed_mode: mode_tip = "🚀 Generated with High-Speed + HD Mode" else: mode_tip = "⏱️ Generated with Low Resolution Mode | Visit https://omnicreator.net for High-Speed HD generation" - status_message = f"{mode_tip}\n{t('status_completed_message', lang).format(message=message)}" + status_message = f"{mode_tip}\n✅ Completed: {message}" set_active_task(client_ip, False) # 解锁任务 print(f"✅ [Multi Edit] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) @@ -853,18 +862,18 @@ def multi_image_edit_interface(input_image1, input_image2, input_image3, prompt, else: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Multi Edit] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Multi Edit] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= # 文生图接口 # ============================================================================= -def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, progress=gr.Progress()): +def text_to_image_interface(prompt, aspect_ratio, request: gr.Request, progress=gr.Progress()): """文生图接口""" try: client_ip = request.client.host @@ -873,21 +882,22 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro client_ip = x_forwarded_for if not prompt or prompt.strip() == "": - return "", t("error_enter_prompt", lang), gr.update(visible=False) + return "", "❌ Please enter a prompt", gr.update(visible=False) if len(prompt.strip()) <= 3: - return "", t("error_prompt_too_short", lang), gr.update(visible=False) + return "", "❌ Prompt is too short. Please provide detailed description.", gr.update(visible=False) except Exception as e: - return "", t("error_request_processing", lang), gr.update(visible=False) + return "", "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") country_config = rate_limit_config.get_country_config(country) current_phase = get_ip_phase(client_ip) current_count = get_ip_generation_count(client_ip) + is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查是否有活动任务(3分钟内) is_active, remaining_seconds = has_active_task(client_ip) @@ -900,13 +910,13 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro # 检查是否被封锁 if current_phase == 'blocked': - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: is_limited, wait_minutes, _ = check_rate_limit_for_phase(client_ip, current_phase) if is_limited: wait_minutes_int = int(wait_minutes) + 1 - return "", t("error_free_limit_wait", lang).format(wait_minutes_int=wait_minutes_int), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", f"⏰ Rate limit reached. Please wait {wait_minutes_int} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # 决定任务参数(在progress_callback之前定义,以便在回调中使用) if use_high_speed_mode: @@ -941,7 +951,7 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro if message and message.startswith("HF_LIMIT_EXCEEDED:"): set_active_task(client_ip, False) - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -949,17 +959,17 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) - return blurred_html, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) result_html = create_result_image_html(result_url) # 为T2I生成3个操作按钮 action_html = "" - if task_uuid and lang not in ["zh", "hi", "ru"]: + if task_uuid and not is_restricted: task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" from urllib.parse import quote encoded_prompt = quote(prompt.strip()) if prompt else "" @@ -990,7 +1000,7 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro """ - if show_like_tip or lang in ["zh", "hi", "ru"]: + if show_like_tip or is_restricted: action_html += create_like_tip_html() # 添加模式提示信息 @@ -998,7 +1008,7 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro mode_tip = "🚀 Generated with High-Speed + HD Mode (800×800)" else: mode_tip = "⏱️ Generated with Low Resolution Mode (576×576) | Visit https://omnicreator.net for High-Speed HD generation" - status_message = f"{mode_tip}\n{t('status_completed_message', lang).format(message=message)}" + status_message = f"{mode_tip}\n✅ Completed: {message}" set_active_task(client_ip, False) # 解锁任务 print(f"✅ [Text2Image] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) @@ -1006,18 +1016,18 @@ def text_to_image_interface(prompt, aspect_ratio, lang, request: gr.Request, pro else: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Text2Image] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Text2Image] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= # 图片放大接口 # ============================================================================= -def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr.Progress()): +def image_upscale_interface(input_image, request: gr.Request, progress=gr.Progress()): """图片放大接口""" try: client_ip = request.client.host @@ -1026,17 +1036,18 @@ def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr. client_ip = x_forwarded_for if input_image is None: - return "", t("error_upload_first", lang), gr.update(visible=False) + return "", "❌ Please upload an image first", gr.update(visible=False) except Exception as e: - return "", t("error_request_processing", lang), gr.update(visible=False) + return "", "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") current_phase = get_ip_phase(client_ip) current_count = get_ip_generation_count(client_ip) + is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查是否有活动任务(3分钟内) is_active, remaining_seconds = has_active_task(client_ip) @@ -1045,13 +1056,13 @@ def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr. # 检查是否被封锁 if current_phase == 'blocked': - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: is_limited, wait_minutes, _ = check_rate_limit_for_phase(client_ip, current_phase) if is_limited: wait_minutes_int = int(wait_minutes) + 1 - return "", t("error_free_limit_wait", lang).format(wait_minutes_int=wait_minutes_int), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", f"⏰ Rate limit reached. Please wait {wait_minutes_int} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # NSFW检测 is_nsfw_task, _ = check_nsfw_for_input(input_image, country, current_count, client_ip) @@ -1067,17 +1078,20 @@ def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr. # 设置任务锁定 set_active_task(client_ip, True) - task_priority = 1 if current_count < rate_limit_config.HIGH_PRIORITY_COUNT else 0 + # 判断是否使用高速高清模式 + use_high_speed_mode = current_count < rate_limit_config.HIGH_SPEED_HD_COUNT + task_priority = 1 if use_high_speed_mode else 0 record_generation_attempt(client_ip, current_phase) updated_count = get_ip_generation_count(client_ip) - print(f"✅ [Upscale] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Priority: {task_priority}", flush=True) + mode_info = "High-Speed HD" if use_high_speed_mode else "Standard" + print(f"✅ [Upscale] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Mode: {mode_info}", flush=True) input_url, result_url, message, task_uuid = process_image_upscale(input_image, progress_callback, priority=task_priority, client_ip=client_ip) if message and message.startswith("HF_LIMIT_EXCEEDED:"): set_active_task(client_ip, False) - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -1086,15 +1100,15 @@ def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr. # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) - return blurred_html, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) result_html = create_result_image_html(result_url) action_html = "" - if task_uuid and lang not in ["zh", "hi", "ru"]: + if task_uuid and not is_restricted: task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" action_html = f"""
@@ -1117,26 +1131,33 @@ def image_upscale_interface(input_image, lang, request: gr.Request, progress=gr. '>💾 Download HD Image
""" - if show_like_tip or lang in ["zh", "hi", "ru"]: + if show_like_tip or is_restricted: action_html += create_like_tip_html() set_active_task(client_ip, False) # 解锁任务 print(f"✅ [Upscale] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) - return result_html, t("status_completed_message", lang).format(message=message), gr.update(value=action_html, visible=bool(action_html)) + + # 添加模式提示 + if use_high_speed_mode: + status_msg = f"✅ Completed with High-Speed HD Mode: {message}" + else: + status_msg = f"✅ Completed with Standard Mode: {message}\n💡 Visit https://omnicreator.net for High-Speed HD generation" + + return result_html, status_msg, gr.update(value=action_html, visible=bool(action_html)) else: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Upscale] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) # 解锁任务 print(f"❌ [Upscale] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= # 换脸接口 # ============================================================================= -def face_swap_interface(target_editor, source_face_image, lang, request: gr.Request, progress=gr.Progress()): +def face_swap_interface(target_editor, source_face_image, request: gr.Request, progress=gr.Progress()): """换脸接口 - 支持从ImageEditor提取mask""" try: client_ip = request.client.host @@ -1149,7 +1170,7 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ mask_image = None if target_editor is None: - return "", t("error_upload_target_image", lang), gr.update(visible=False) + return "", "❌ Please upload a target image", gr.update(visible=False) # ImageEditor返回字典格式: {"background": PIL, "layers": [PIL], "composite": PIL} if isinstance(target_editor, dict): @@ -1165,20 +1186,21 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ target_image = target_editor if target_image is None: - return "", t("error_upload_target_image", lang), gr.update(visible=False) + return "", "❌ Please upload a target image", gr.update(visible=False) if source_face_image is None: - return "", t("error_upload_source_face", lang), gr.update(visible=False) + return "", "❌ Please upload a source face image", gr.update(visible=False) except Exception as e: - return "", t("error_request_processing", lang), gr.update(visible=False) + return "", "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") current_phase = get_ip_phase(client_ip) current_count = get_ip_generation_count(client_ip) + is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查活动任务 is_active, remaining_seconds = has_active_task(client_ip) @@ -1187,12 +1209,12 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ # 检查是否被封锁 if current_phase == 'blocked': - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: is_limited, wait_minutes, _ = check_rate_limit_for_phase(client_ip, current_phase) if is_limited: - return "", t("error_free_limit_wait", lang).format(wait_minutes_int=int(wait_minutes)+1), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", f"⏰ Rate limit reached. Please wait {int(wait_minutes)+1} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # NSFW检测 - 检测target和source图片 is_nsfw_task, _ = check_nsfw_for_input(target_image, country, current_count, client_ip) @@ -1208,18 +1230,22 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ try: set_active_task(client_ip, True) - task_priority = 1 if current_count < rate_limit_config.HIGH_PRIORITY_COUNT else 0 + + # 判断是否使用高速高清模式 + use_high_speed_mode = current_count < rate_limit_config.HIGH_SPEED_HD_COUNT + task_priority = 1 if use_high_speed_mode else 0 record_generation_attempt(client_ip, current_phase) updated_count = get_ip_generation_count(client_ip) has_mask = "Yes" if mask_image is not None else "No" - print(f"✅ [FaceSwap] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Priority: {task_priority}, HasMask: {has_mask}", flush=True) + mode_info = "High-Speed HD" if use_high_speed_mode else "Standard" + print(f"✅ [FaceSwap] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Mode: {mode_info}, HasMask: {has_mask}", flush=True) input_url, result_url, message, task_uuid = process_face_swap(target_image, source_face_image, mask_image, progress_callback, priority=task_priority, client_ip=client_ip) if message and message.startswith("HF_LIMIT_EXCEEDED:"): set_active_task(client_ip, False) - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -1228,15 +1254,15 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) - return blurred_html, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) result_html = create_result_image_html(result_url) action_html = "" - if task_uuid and lang not in ["zh", "hi", "ru"]: + if task_uuid and not is_restricted: task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" action_html = f"""
@@ -1259,26 +1285,33 @@ def face_swap_interface(target_editor, source_face_image, lang, request: gr.Requ '>💾 Download HD Image
""" - if show_like_tip or lang in ["zh", "hi", "ru"]: + if show_like_tip or is_restricted: action_html += create_like_tip_html() set_active_task(client_ip, False) print(f"✅ [FaceSwap] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) - return result_html, t("status_completed_message", lang).format(message=message), gr.update(value=action_html, visible=bool(action_html)) + + # 添加模式提示 + if use_high_speed_mode: + status_msg = f"✅ Completed with High-Speed HD Mode: {message}" + else: + status_msg = f"✅ Completed with Standard Mode: {message}\n💡 Visit https://omnicreator.net for High-Speed HD generation" + + return result_html, status_msg, gr.update(value=action_html, visible=bool(action_html)) else: set_active_task(client_ip, False) print(f"❌ [FaceSwap] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) print(f"❌ [FaceSwap] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= # 去水印接口 # ============================================================================= -def watermark_removal_interface(input_image, force_removal, lang, request: gr.Request, progress=gr.Progress()): +def watermark_removal_interface(input_image, force_removal, request: gr.Request, progress=gr.Progress()): """去水印接口 - 支持强力模式""" try: client_ip = request.client.host @@ -1287,17 +1320,18 @@ def watermark_removal_interface(input_image, force_removal, lang, request: gr.Re client_ip = x_forwarded_for if input_image is None: - return "", t("error_upload_image", lang), gr.update(visible=False) + return "", "❌ Please upload an image", gr.update(visible=False) except Exception as e: - return "", t("error_request_processing", lang), gr.update(visible=False) + return "", "❌ Failed to process request", gr.update(visible=False) geo_info = util.IP_Country_Cache.get(client_ip, {"country": "Unknown"}) country = geo_info.get("country", "Unknown") current_phase = get_ip_phase(client_ip) current_count = get_ip_generation_count(client_ip) + is_restricted = rate_limit_config.is_restricted_country(country) show_like_tip = rate_limit_config.should_show_like_tip(country, current_count) - redirect_url = rate_limit_config.get_redirect_url(country, lang) + redirect_url = rate_limit_config.get_redirect_url(country, "en") # 检查活动任务 is_active, remaining_seconds = has_active_task(client_ip) @@ -1306,12 +1340,12 @@ def watermark_removal_interface(input_image, force_removal, lang, request: gr.Re # 检查是否被封锁 if current_phase == 'blocked': - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']: is_limited, wait_minutes, _ = check_rate_limit_for_phase(client_ip, current_phase) if is_limited: - return "", t("error_free_limit_wait", lang).format(wait_minutes_int=int(wait_minutes)+1), gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) + return "", f"⏰ Rate limit reached. Please wait {int(wait_minutes)+1} minutes before trying again.", gr.update(value=create_rate_limit_button_html(redirect_url), visible=True) # NSFW检测 is_nsfw_task, _ = check_nsfw_for_input(input_image, country, current_count, client_ip) @@ -1326,18 +1360,22 @@ def watermark_removal_interface(input_image, force_removal, lang, request: gr.Re try: set_active_task(client_ip, True) - task_priority = 1 if current_count < rate_limit_config.HIGH_PRIORITY_COUNT else 0 + + # 判断是否使用高速高清模式 + use_high_speed_mode = current_count < rate_limit_config.HIGH_SPEED_HD_COUNT + task_priority = 1 if use_high_speed_mode else 0 record_generation_attempt(client_ip, current_phase) updated_count = get_ip_generation_count(client_ip) force_mode = "Yes" if force_removal else "No" - print(f"✅ [Watermark] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Priority: {task_priority}, ForceMode: {force_mode}", flush=True) + mode_info = "High-Speed HD" if use_high_speed_mode else "Standard" + print(f"✅ [Watermark] Processing started - IP: {client_ip}, Country: {country}, Phase: {current_phase}, Count: {updated_count}, Mode: {mode_info}, ForceMode: {force_mode}", flush=True) input_url, result_url, message, task_uuid = process_watermark_removal(input_image, progress_callback, priority=task_priority, client_ip=client_ip, force_removal=force_removal) if message and message.startswith("HF_LIMIT_EXCEEDED:"): set_active_task(client_ip, False) - return "", t("error_free_limit_reached", lang), gr.update(value=create_blocked_button_html(redirect_url), visible=True) + return "", "🚫 You have reached the free generation limit.", gr.update(value=create_blocked_button_html(redirect_url), visible=True) if result_url: # 检查结果图片NSFW @@ -1346,15 +1384,15 @@ def watermark_removal_interface(input_image, force_removal, lang, request: gr.Re # 应用模糊处理 if is_nsfw_task: - nsfw_response = create_nsfw_blurred_response(result_url, redirect_url, lang) + nsfw_response = create_nsfw_blurred_response(result_url, redirect_url) if nsfw_response: blurred_html, nsfw_button_html = nsfw_response set_active_task(client_ip, False) - return blurred_html, t("warning_content_filter", lang), gr.update(value=nsfw_button_html, visible=True) + return blurred_html, "⚠️ Content detected by filter. Visit website to unlock.", gr.update(value=nsfw_button_html, visible=True) result_html = create_result_image_html(result_url) action_html = "" - if task_uuid and lang not in ["zh", "hi", "ru"]: + if task_uuid and not is_restricted: task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}" action_html = f"""
@@ -1372,20 +1410,27 @@ def watermark_removal_interface(input_image, force_removal, lang, request: gr.Re '>🚀 Unlimited Removal
""" - if show_like_tip or lang in ["zh", "hi", "ru"]: + if show_like_tip or is_restricted: action_html += create_like_tip_html() set_active_task(client_ip, False) print(f"✅ [Watermark] Completed - IP: {client_ip}, TaskUUID: {task_uuid}, Result: {result_url[:80]}...", flush=True) - return result_html, t("status_completed_message", lang).format(message=message), gr.update(value=action_html, visible=bool(action_html)) + + # 添加模式提示 + if use_high_speed_mode: + status_msg = f"✅ Completed with High-Speed HD Mode: {message}" + else: + status_msg = f"✅ Completed with Standard Mode: {message}\n💡 Visit https://omnicreator.net for High-Speed HD generation" + + return result_html, status_msg, gr.update(value=action_html, visible=bool(action_html)) else: set_active_task(client_ip, False) print(f"❌ [Watermark] Failed - IP: {client_ip}, Error: {message}", flush=True) - return "", t("error_processing_failed", lang).format(message=message), gr.update(visible=False) + return "", f"❌ Processing failed: {message}", gr.update(visible=False) except Exception as e: set_active_task(client_ip, False) print(f"❌ [Watermark] Exception - IP: {client_ip}, Error: {str(e)}", flush=True) - return "", t("error_processing_exception", lang).format(error=str(e)), gr.update(visible=False) + return "", f"❌ Error: {str(e)}", gr.update(visible=False) # ============================================================================= @@ -1403,49 +1448,36 @@ def create_app(): .result-area { margin-top: 20px; padding: 20px; border-radius: 10px; background-color: #f8f9fa; } """ ) as app: - - lang_state = gr.State("en") # 主标题 - header_title = gr.HTML(f""" + gr.HTML("""

- {t('header_title', 'en')} + 🎨 Omni Editor 2.0

""") - with gr.Row(elem_classes=["news-banner-row"]): - with gr.Column(scale=1, min_width=400): - news_banner = gr.HTML(f""" - -
- - 🎉 Please give us a ❤️ if you think it's helpful - -
- """, visible=True) - - with gr.Column(scale=0, min_width=160, elem_classes=["banner-lang-selector"]): - lang_dropdown = gr.Dropdown( - choices=[("English", "en"), ("中文", "zh")], - value="en", - label="🌐", - show_label=True, - interactive=True, - container=False - ) + # Banner + gr.HTML(""" + +
+ + Please give us a ❤️ if you find it helpful. Free trials refreshed every few days. + +
+ """, visible=True) # ============================================================================= # 多Tab界面 @@ -1455,31 +1487,31 @@ def create_app(): # ============================================================================= # Tab 1: 单图编辑 # ============================================================================= - with gr.Tab(t("tab_single_image_edit", "en")) as single_edit_tab: + with gr.Tab("🖼️ Single Image Edit") as single_edit_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown(t("upload_image_header", "en")) - single_input_image = gr.Image(label=t("upload_image_label", "en"), type="pil", height=512, elem_classes=["upload-area"]) - gr.Markdown(t("editing_instructions_header", "en")) - single_prompt = gr.Textbox(label=t("prompt_input_label", "en"), placeholder=t("prompt_input_placeholder", "en"), lines=3) - single_edit_btn = gr.Button(t("start_editing_button", "en"), variant="primary", size="lg") + gr.Markdown("### 📤 Upload Image") + single_input_image = gr.Image(label="Select image to edit", type="pil", height=512, elem_classes=["upload-area"]) + gr.Markdown("### ✏️ Editing Instructions") + single_prompt = gr.Textbox(label="Prompt", placeholder="Describe what you want to change in the image...", lines=3) + single_edit_btn = gr.Button("🎨 Start Editing", variant="primary", size="lg") with gr.Column(scale=1): - gr.Markdown(t("editing_result_header", "en")) - single_output_image = gr.HTML(label=t("output_image_label", "en"), elem_classes=["result-area"]) + gr.Markdown("### 🎯 Editing Result") + single_output_image = gr.HTML(label="Output Image", elem_classes=["result-area"]) single_output_url = gr.State() # 隐藏state保存URL用于Use as Input - single_use_as_input_btn = gr.Button(t("use_as_input_button", "en"), variant="secondary", size="sm") - single_status = gr.Textbox(label=t("status_output_label", "en"), lines=2, interactive=False) + single_use_as_input_btn = gr.Button("🔄 Use as Input", variant="secondary", size="sm") + single_status = gr.Textbox(label="Processing Status", lines=2, interactive=False) single_action_buttons = gr.HTML(visible=False) - gr.Markdown(t("prompt_examples_header", "en")) + gr.Markdown("### 💡 Prompt Examples") with gr.Row(): for prompt in ["Change background to beach sunset", "Add rainbow in the sky", "Make it look like oil painting", "Remove the background", "Change outfit to red dress"]: gr.Button(prompt, size="sm").click(lambda p=prompt: p, outputs=single_prompt) single_edit_btn.click( fn=edit_image_interface, - inputs=[single_input_image, single_prompt, lang_state], + inputs=[single_input_image, single_prompt], outputs=[single_output_image, single_output_url, single_status, single_action_buttons], show_progress=True, concurrency_limit=20 @@ -1507,15 +1539,15 @@ def create_app(): # ============================================================================= # Tab 2: 多图编辑 # ============================================================================= - with gr.Tab(t("tab_multi_image_edit", "en")) as multi_edit_tab: + with gr.Tab("🖼️🖼️ Multi-Image Edit") as multi_edit_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown(t("multi_image_upload_header", "en")) + gr.Markdown("### 📤 Upload Images") # 3个图片组件放在同一排 with gr.Row(): - multi_input_image1 = gr.Image(label=t("multi_image1_label", "en"), type="pil", height=200, elem_classes=["upload-area"]) - multi_input_image2 = gr.Image(label=t("multi_image2_label", "en"), type="pil", height=200, elem_classes=["upload-area"]) - multi_input_image3 = gr.Image(label=t("multi_image3_label", "en"), type="pil", height=200, elem_classes=["upload-area"]) + multi_input_image1 = gr.Image(label="Image 1", type="pil", height=200, elem_classes=["upload-area"]) + multi_input_image2 = gr.Image(label="Image 2", type="pil", height=200, elem_classes=["upload-area"]) + multi_input_image3 = gr.Image(label="Image 3 (Optional)", type="pil", height=200, elem_classes=["upload-area"]) gr.Markdown("📐 Output Size") multi_aspect_ratio = gr.Radio( @@ -1525,24 +1557,24 @@ def create_app(): info="Choose output dimensions or Auto for original sizing" ) - gr.Markdown(t("multi_prompt_header", "en")) - multi_prompt = gr.Textbox(label=t("multi_prompt_label", "en"), placeholder=t("multi_prompt_placeholder", "en"), lines=3) - multi_edit_btn = gr.Button(t("multi_edit_button", "en"), variant="primary", size="lg") + gr.Markdown("### ✏️ Editing Instructions") + multi_prompt = gr.Textbox(label="Prompt", placeholder="Describe how to combine or edit these images...", lines=3) + multi_edit_btn = gr.Button("🎨 Start Multi-Image Editing", variant="primary", size="lg") with gr.Column(scale=1): - gr.Markdown(t("editing_result_header", "en")) - multi_output_image = gr.HTML(label=t("output_image_label", "en"), elem_classes=["result-area"]) - multi_status = gr.Textbox(label=t("status_output_label", "en"), lines=2, interactive=False) + gr.Markdown("### 🎯 Editing Result") + multi_output_image = gr.HTML(label="Output Image", elem_classes=["result-area"]) + multi_status = gr.Textbox(label="Processing Status", lines=2, interactive=False) multi_action_buttons = gr.HTML(visible=False) - gr.Markdown(t("multi_examples_header", "en")) + gr.Markdown("### 💡 Prompt Examples") with gr.Row(): for prompt in ["Merge these two animals into one image", "Combine the elements from both images", "Create a scene with objects from all images"]: gr.Button(prompt, size="sm").click(lambda p=prompt: p, outputs=multi_prompt) multi_edit_btn.click( fn=multi_image_edit_interface, - inputs=[multi_input_image1, multi_input_image2, multi_input_image3, multi_prompt, multi_aspect_ratio, lang_state], + inputs=[multi_input_image1, multi_input_image2, multi_input_image3, multi_prompt, multi_aspect_ratio], outputs=[multi_output_image, multi_status, multi_action_buttons], show_progress=True, concurrency_limit=20 @@ -1551,11 +1583,11 @@ def create_app(): # ============================================================================= # Tab 3: 文生图 # ============================================================================= - with gr.Tab(t("tab_text_to_image", "en")) as t2i_tab: + with gr.Tab("✨ Text to Image") as t2i_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown(t("t2i_prompt_header", "en")) - t2i_prompt = gr.Textbox(label=t("t2i_prompt_label", "en"), placeholder=t("t2i_prompt_placeholder", "en"), lines=5) + gr.Markdown("### ✏️ Describe Your Image") + t2i_prompt = gr.Textbox(label="Prompt", placeholder="Describe the image you want to generate...", lines=5) gr.Markdown("📐 Output Size") t2i_aspect_ratio = gr.Radio( @@ -1565,23 +1597,23 @@ def create_app(): info="Choose output dimensions for generated image" ) - t2i_btn = gr.Button(t("t2i_generate_button", "en"), variant="primary", size="lg") + t2i_btn = gr.Button("🎨 Generate Image", variant="primary", size="lg") with gr.Column(scale=1): - gr.Markdown(t("t2i_result_header", "en")) - t2i_output_image = gr.HTML(label=t("t2i_output_label", "en"), elem_classes=["result-area"]) + gr.Markdown("### 🎯 Generated Image") + t2i_output_image = gr.HTML(label="Output Image", elem_classes=["result-area"]) t2i_output_url = gr.State() # 保存URL用于生成按钮链接 - t2i_status = gr.Textbox(label=t("status_output_label", "en"), lines=2, interactive=False) + t2i_status = gr.Textbox(label="Processing Status", lines=2, interactive=False) t2i_action_buttons = gr.HTML(visible=False) - gr.Markdown(t("t2i_examples_header", "en")) + gr.Markdown("### 💡 Prompt Examples") with gr.Row(): for prompt in ["A beautiful young woman standing by the seaside at sunset", "A majestic dragon flying over a medieval castle", "A cute cat wearing a wizard hat, digital art", "Futuristic city skyline at night with neon lights"]: gr.Button(prompt, size="sm").click(lambda p=prompt: p, outputs=t2i_prompt) t2i_btn.click( fn=text_to_image_interface, - inputs=[t2i_prompt, t2i_aspect_ratio, lang_state], + inputs=[t2i_prompt, t2i_aspect_ratio], outputs=[t2i_output_image, t2i_status, t2i_action_buttons], show_progress=True, concurrency_limit=20 @@ -1590,22 +1622,22 @@ def create_app(): # ============================================================================= # Tab 4: 图片放大 # ============================================================================= - with gr.Tab(t("tab_image_upscale", "en")) as upscale_tab: + with gr.Tab("🔍 Image Upscale") as upscale_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown(t("upscale_upload_header", "en")) - upscale_input_image = gr.Image(label=t("upscale_input_label", "en"), type="pil", height=400, elem_classes=["upload-area"]) - upscale_btn = gr.Button(t("upscale_button", "en"), variant="primary", size="lg") + gr.Markdown("### 📤 Upload Image") + upscale_input_image = gr.Image(label="Select image to upscale", type="pil", height=400, elem_classes=["upload-area"]) + upscale_btn = gr.Button("🔍 Upscale Image", variant="primary", size="lg") with gr.Column(scale=1): - gr.Markdown(t("upscale_result_header", "en")) - upscale_output_image = gr.HTML(label=t("upscale_output_label", "en"), elem_classes=["result-area"]) - upscale_status = gr.Textbox(label=t("status_output_label", "en"), lines=2, interactive=False) + gr.Markdown("### 🎯 Upscaled Result") + upscale_output_image = gr.HTML(label="Output Image", elem_classes=["result-area"]) + upscale_status = gr.Textbox(label="Processing Status", lines=2, interactive=False) upscale_action_buttons = gr.HTML(visible=False) upscale_btn.click( fn=image_upscale_interface, - inputs=[upscale_input_image, lang_state], + inputs=[upscale_input_image], outputs=[upscale_output_image, upscale_status, upscale_action_buttons], show_progress=True, concurrency_limit=20 @@ -1614,13 +1646,13 @@ def create_app(): # ============================================================================= # Tab 5: 换脸 # ============================================================================= - with gr.Tab(t("tab_face_swap", "en")) as faceswap_tab: + with gr.Tab("👤 Face Swap") as faceswap_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown(t("faceswap_target_header", "en")) + gr.Markdown("### 📤 Upload Target Image") gr.Markdown("*If multiple faces exist, draw on the face you want to replace*", elem_classes=["hint-text"]) faceswap_target_editor = gr.ImageEditor( - label=t("faceswap_target_label", "en"), + label="Target image (draw on face to replace if multiple faces)", type="pil", height=350, brush=gr.Brush(colors=["#FFFFFF"], default_size=80, color_mode="fixed"), @@ -1628,19 +1660,19 @@ def create_app(): layers=False, sources=["upload", "clipboard"] ) - gr.Markdown(t("faceswap_source_header", "en")) - faceswap_source = gr.Image(label=t("faceswap_source_label", "en"), type="pil", height=256) - faceswap_btn = gr.Button(t("faceswap_button", "en"), variant="primary", size="lg") + gr.Markdown("### 📤 Upload Source Face") + faceswap_source = gr.Image(label="Source face image", type="pil", height=256) + faceswap_btn = gr.Button("👤 Swap Face", variant="primary", size="lg") with gr.Column(scale=1): - gr.Markdown(t("faceswap_result_header", "en")) - faceswap_output = gr.HTML(label=t("faceswap_output_label", "en"), elem_classes=["result-area"]) - faceswap_status = gr.Textbox(label=t("status_output_label", "en"), lines=2, interactive=False) + gr.Markdown("### 🎯 Face Swap Result") + faceswap_output = gr.HTML(label="Output Image", elem_classes=["result-area"]) + faceswap_status = gr.Textbox(label="Processing Status", lines=2, interactive=False) faceswap_action_buttons = gr.HTML(visible=False) faceswap_btn.click( fn=face_swap_interface, - inputs=[faceswap_target_editor, faceswap_source, lang_state], + inputs=[faceswap_target_editor, faceswap_source], outputs=[faceswap_output, faceswap_status, faceswap_action_buttons], show_progress=True, concurrency_limit=20 @@ -1652,7 +1684,7 @@ def create_app(): with gr.Tab("🧽 Remove Watermark") as watermark_tab: with gr.Row(): with gr.Column(scale=1): - gr.Markdown("🖼️ Upload Image with Watermark") + gr.Markdown("### 🧽 Upload Image") watermark_input = gr.Image(label="Select image to remove watermark", type="pil", height=400, elem_classes=["upload-area"]) watermark_force_removal = gr.Checkbox( label="💪 Force Removal", @@ -1670,7 +1702,7 @@ def create_app(): watermark_btn.click( fn=watermark_removal_interface, - inputs=[watermark_input, watermark_force_removal, lang_state], + inputs=[watermark_input, watermark_force_removal], outputs=[watermark_output, watermark_status, watermark_action_buttons], show_progress=True, concurrency_limit=20 @@ -1704,26 +1736,20 @@ def create_app(): # ============================================================================= # SEO内容区域 # ============================================================================= - seo_html = gr.HTML() - - def get_seo_html(lang): - if lang in ["zh", "hi", "ru"]: - return "" - - return f""" + gr.HTML("""
-

🎨 {t('seo_unlimited_title', lang)}

-

{t('seo_unlimited_desc', lang)}

+

🎨 Unlimited AI Image Generation & Editing

+

Access unlimited image generation, video creation, and advanced editing features. No time limitation, no ads, no watermark.

🚀 {t('seo_unlimited_button', lang)} + ">🚀 Get Unlimited Access
@@ -1732,16 +1758,16 @@ def create_app():

⚡ Performance Highlights

-

🏁 Image Generation

-

896×896 in under 10 seconds on RTX 5090 (32GB VRAM)

+

🏁 Few-Step Flow Matching

+

4–8 NFE with Karras sigmas + RK2/RK4

-

🎥 Video Generation

-

3-second 320p video in 30 seconds

+

🎥 Temporal-Ready

+

Video latents + shared attention improve consistency

-

💡 Knowledge Distillation

-

Real-time inference performance achieved

+

💡 Hybrid ODE Solver

+

Heun/RK4 + Flow Matching trajectory integration

@@ -1767,121 +1793,296 @@ def create_app():

- -
-

+ +
+

🤖 Omni Creator 2.0: 8B Unified Multi-Modal Diffusion Transformer

-
-

- Omni Creator 2.0 is an 8-billion parameter native Multi-Modal Diffusion Transformer (MM-DiT). - It unifies Text-to-Image, high-fidelity pixel-level editing, and Image-to-Video generation inside a single differentiable architecture. -

-

- Existing approaches often split into specialized systems: DiT-style generators can be strong for static synthesis but struggle with temporal coherence, while MLLM-based editors follow instructions well but may lose pixel-level fidelity. - Omni Creator 2.0 bridges both by design. -

-
-
Core Architectural Innovations
-
-
1) Spatio-Temporal 3D Shifted Window Attention — window partitioning with temporal shifting (Swin-style, adapted for diffusion) to improve long-range temporal dependency modeling and reduce flickering.
-
2) Native Multi-Image Conditioning + Adaptive Fusion — built-in visual projector supports up to 3 concurrent reference images; Adaptive Multi-Modal Gating dynamically balances text, image references, and temporal context.
-
3) HPC-Ready Optimization — production-oriented inference with FP8 support, RoPE, and RMSNorm for stable scaling to longer sequences and higher resolutions.
+

+ 8B-parameter native MM-DiT unifying T2I, pixel-level editing, and I2V generation. + Uses CLIP/T5-style text encoders and visual conditioners to deliver high-fidelity multi-modal results with shared transformer backbone. +

+ + +
+
+ RoPE + AdaLN-Zero DiT Blocks +

Multi-head attention with timestep-conditioned modulation

+
+
+ Adaptive Multi-Modal Gating +

Learned fusion of text, 3× images, and temporal context

+
+
+ HPC-Ready Optimization +

FP8 + RoPE + RMSNorm for production-scale inference

+
+
+ + +
+
📊 AdaLN-Zero + AMG (Full Stack)
+
+# 1) Modal fusion (text / up to 3 imgs / temporal)
+α = Softmax(MLP([ctxt; cimg; ctmp]));  C = αtxt·ctxt + Σ αi·cimg,i + αtmp·ctmp
+# 2) Time-conditioned modulation
+h = TEmbed(t) ⊕ C;  (γ, β, λ) = MLP(h)
+# 3) RoPE self-attn + gated residual
+Q = RoPE(Wq·LN(x)); K = RoPE(Wk·LN(x)); V = Wv·LN(x)
+A = Softmax((QKT/√d) + Brel) · V
+x ← x + λ ⊙ A · (1+γ) + β + CrossAttn(x, C)
+# 4) AdaLN-zero modulated SwiGLU FFN
+u = SwiGLU(W1·LN(x));   x ← x + λ ⊙ (W2·u) · (1+γ) + β +
+
+
+ + +
+

+ ⚡ OmniScheduler: Unified Hybrid Flow-Diffusion Sampler +

+

+ Sampling framework that couples Flow Matching, Karras sigmas, and Heun/RK4 ODE solvers for fast 4–8 step generation. +

+ + +
+
+

🎯 Few-Step Flow Matching

+

Supports velocity/epsilon/sample prediction with flow-to-velocity conversion, enabling 4–8 step inference.

+
+
+

🔄 Multi-Stage Sampling

+

Coarse-to-fine pipeline: ~70% steps for coarse draft, optional refine passes for details.

+
+
+

📈 RK4 Hybrid ODE

+

Runge-Kutta 4th order solver with flow matching conditioning for optimal trajectory evolution.

+
+
+ + +
+
🔢 Flow Matching Formulation
+
+

Given data distribution p₁(x) and noise distribution p₀(z) = N(0, I), the Rectified Flow defines:

+
+ x_t = (1 - t) · z + t · x    where t ∈ [0, 1] +
+

The velocity field v_θ(x_t, t) is trained to match the conditional velocity:

+
+ L_FM = E_{t,x,z}[ ||v_θ(x_t, t) - (x - z)||² ] +
+

At inference, we solve the ODE: dx/dt = v_θ(x_t, t) from t=0 to t=1

+
+
+ + +
+
π π-Flow Policy Network (Coarse Trajectory)
+
+
Instead of evaluating the model dozens of times, a lightweight policy network can predict a multi-step velocity trajectory in one forward pass.
+
+
# One-shot trajectory prediction (coarse stage)
+
v_{0:S-1} = π_φ(z₀, c, t_grid) + x_{k+1} = x_k + v_k · Δt (k = 0..S-1)
+
+
How it integrates with OmniScheduler:
+
+
Stage-1 (coarse): apply the predicted velocities directly (policy rollout) to rapidly move along the flow-matching path.
+
Stage-2 (refine): optionally switch to Heun/RK4 higher-order updates for detail recovery and stability.
+
Multi-modal conditioning: the policy is conditioned on aggregated text/visual context + time embedding, outputting velocity fields matching latent shape.
-
-
Mechanism Sketch
-
# Fourier timestep embedding (DiT) -t_freq = [cos(t · ω_1..m), sin(t · ω_1..m)] -t_emb = MLP(t_freq) - -# RoPE + RMSNorm stabilized attention -Q,K,V = Wq·RMSNorm(x), Wk·RMSNorm(x), Wv·RMSNorm(x) -Q,K = RoPE(Q), RoPE(K) -Attn = Softmax((QK^T)/sqrt(d) + B_rel) V - -# AdaLN-Zero modulation (diffusion conditioning) -shift,scale,gate = Linear(t_emb) -x = x + gate * Attn( (1+scale) ⊙ RMSNorm(x) + shift ) - -# Multi-modal fusion (text + up to 3 images) -ctx = concat(E_text, P_visual(I_1..I_3)) -x = x + CrossAttn(RMSNorm(x), ctx) - -# High-throughput FFN -x = x + gate_mlp * SwiGLU(RMSNorm(x))
+
+ + +
+
🎲 Multi-Stage Sampling Pipeline
+
+
+
📷
+
Input
+
Text + Images
+
+
+
+
+
Stage 1
+
Coarse (≈70%)
+
Euler/Heun, few steps
+
+
+
+
💎
+
Stage 2
+
Refine (≈30%)
+
RK4 optional
+
+
+
+
🎨
+
Output
+
HD Image/Video
+
-
- """ - - # 收集所有需要更新的UI组件 - all_ui_components = [ - header_title, news_banner, - single_edit_tab, multi_edit_tab, t2i_tab, upscale_tab, faceswap_tab, watermark_tab, - seo_html, - ] - - def update_ui_lang(lang): - show_banner = lang not in ["zh", "hi", "ru"] - return { - header_title: gr.update(value=f""" -
-

- {t('header_title', lang)} -

-
"""), - news_banner: gr.update(visible=show_banner), - single_edit_tab: gr.update(label=t("tab_single_image_edit", lang)), - multi_edit_tab: gr.update(label=t("tab_multi_image_edit", lang)), - t2i_tab: gr.update(label=t("tab_text_to_image", lang)), - upscale_tab: gr.update(label=t("tab_image_upscale", lang)), - faceswap_tab: gr.update(label=t("tab_face_swap", lang)), - watermark_tab: gr.update(label="🧽 Remove Watermark"), - seo_html: gr.update(value=get_seo_html(lang)), - } + + +
+

+ 🧠 Adaptive Multi-Modal Gating (AMG) +

+

+ Dynamically balancing text, image references, and temporal context through learned gating mechanisms. +

+ +
+
+# Multi-modal context encoding +c_text = TextEncoder(prompt) # CLIP/T5 embeddings +c_imgs = [VisualProjector(img) for img in reference_images] # Up to 3 images +c_temp = TemporalEncoder(prev_frames) # For video generation - def on_lang_change(lang): - return lang, *update_ui_lang(lang).values() - - lang_dropdown.change( - on_lang_change, - inputs=[lang_dropdown], - outputs=[lang_state] + all_ui_components - ) +# Learned gating weights (softmax over modalities) +α = Softmax(MLP([c_text; c_imgs; c_temp])) # α ∈ R^(2+n_imgs) - ip_query_state = gr.State({"status": "pending", "ip": None, "lang": "en"}) - - def on_load_immediate(request: gr.Request): - client_ip = None - try: - client_ip = request.client.host - headers = dict(request.headers) if hasattr(request, 'headers') else {} - x_forwarded_for = headers.get('x-forwarded-for') or headers.get('X-Forwarded-For') - if x_forwarded_for: - client_ip = x_forwarded_for.split(',')[0].strip() - except Exception: - client_ip = "unknown" - - try: - if client_ip in util.IP_Country_Cache: - cached_lang = get_lang_from_ip(client_ip) - query_state = {"ip": client_ip, "cached": True} - return cached_lang, cached_lang, query_state, *update_ui_lang(cached_lang).values() +# Weighted multi-modal fusion +context = α_text · c_text + Σᵢ αᵢ · c_imgs[i] + α_temp · c_temp + +# Cross-attention with gated context +h = h + CrossAttn(Q=h, KV=context) + +# AdaLN-Zero modulation with timestep + modal gates +γ, β, α_gate = MLP(t_emb ⊕ modal_gate) +h = α_gate · LayerNorm(h) · (1 + γ) + β
+
+ +
+
+
💬
+
Text Gate
+
Semantic control
+
+
+
🎨
+
Image Gate
+
Style & identity
+
+
+
🎥
+
Temporal Gate
+
Motion coherence
+
+
+
- detected_lang = get_lang_from_ip(client_ip) - query_state = {"ip": client_ip, "cached": False} - return detected_lang, detected_lang, query_state, *update_ui_lang(detected_lang).values() - except Exception: - query_state = {"ip": client_ip or "unknown", "cached": False} - return "en", "en", query_state, *update_ui_lang("en").values() - - app.load( - on_load_immediate, - inputs=None, - outputs=[lang_state, lang_dropdown, ip_query_state] + all_ui_components, - ) + +
+

+ 📈 State-of-the-Art Model Comparison (2025) +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModelParamsArchitectureTrainingInferenceNFEAcceleration
FLUX.2-Dev32BDiT + MMFlow MatchingEuler/DPM50FP8 + FlashAttn
Qwen-Image20BDiT + MLLMRectified FlowFlowMatch Euler30-50Lightning (4-8步)
Qwen-Image-Edit20BDiT + Dual-BranchFlow MatchingEuler28-50Prompt Rewrite
HunyuanVideo13B+AsymmDiTDiffusionMulti-step50+FP8 + Multi-frame
Wan2.25B/14BDiT + MoEDiffusionMulti-step30-50MoE Routing + FP8
Z-Image-Turbo6BDistilled DiTProgressive DistillFew-step4-8Teacher-Student
Mochi10BVideo DiTDiffusionMulti-step50+ComfyUI Parallel
⭐ Omni Creator 2.08BMM-DiT + AMGπ-Flow + FMRK4 Hybrid4-8Policy Distill + Multi-Stage
+
+ + +
+ Abbreviations: + DiT = Diffusion Transformer | MM = Multi-Modal | MLLM = Multimodal LLM | MoE = Mixture of Experts | + FM = Flow Matching | NFE = Number of Function Evaluations | AMG = Adaptive Multi-Modal Gating +
+
+
+ """) return app