Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -38,7 +38,7 @@ def is_image_nsfw(image):
|
|
| 38 |
try:
|
| 39 |
results = safety_classifier(image)
|
| 40 |
for result in results:
|
| 41 |
-
if result['label'] == 'nsfw' and result['score'] > 0.75:
|
| 42 |
return True
|
| 43 |
return False
|
| 44 |
except Exception as e:
|
|
@@ -67,30 +67,14 @@ pipe = QwenImageEditPlusPipeline.from_pretrained(
|
|
| 67 |
).to(device)
|
| 68 |
|
| 69 |
# بارگذاری LoRA ها
|
| 70 |
-
pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime",
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
pipe.load_lora_weights("dx8152/Qwen-Edit-2509-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
pipe.load_lora_weights("
|
| 77 |
-
|
| 78 |
-
adapter_name="light-restoration")
|
| 79 |
-
pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Relight",
|
| 80 |
-
weight_name="Qwen-Edit-Relight.safetensors",
|
| 81 |
-
adapter_name="relight")
|
| 82 |
-
pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multi-Angle-Lighting",
|
| 83 |
-
weight_name="多角度灯光-251116.safetensors",
|
| 84 |
-
adapter_name="multi-angle-lighting")
|
| 85 |
-
pipe.load_lora_weights("tlennon-ie/qwen-edit-skin",
|
| 86 |
-
weight_name="qwen-edit-skin_1.1_000002750.safetensors",
|
| 87 |
-
adapter_name="edit-skin")
|
| 88 |
-
pipe.load_lora_weights("lovis93/next-scene-qwen-image-lora-2509",
|
| 89 |
-
weight_name="next-scene_lora-v2-3000.safetensors",
|
| 90 |
-
adapter_name="next-scene")
|
| 91 |
-
pipe.load_lora_weights("vafipas663/Qwen-Edit-2509-Upscale-LoRA",
|
| 92 |
-
weight_name="qwen-edit-enhance_64-v3_000001000.safetensors",
|
| 93 |
-
adapter_name="upscale-image")
|
| 94 |
|
| 95 |
pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
|
| 96 |
MAX_SEED = np.iinfo(np.int32).max
|
|
@@ -149,9 +133,7 @@ def translate_prompt(text):
|
|
| 149 |
def update_dimensions_on_upload(image):
|
| 150 |
if image is None:
|
| 151 |
return 1024, 1024
|
| 152 |
-
|
| 153 |
original_width, original_height = image.size
|
| 154 |
-
|
| 155 |
if original_width > original_height:
|
| 156 |
new_width = 1024
|
| 157 |
aspect_ratio = original_height / original_width
|
|
@@ -160,15 +142,13 @@ def update_dimensions_on_upload(image):
|
|
| 160 |
new_height = 1024
|
| 161 |
aspect_ratio = original_width / original_height
|
| 162 |
new_width = int(new_height * aspect_ratio)
|
| 163 |
-
|
| 164 |
new_width = (new_width // 8) * 8
|
| 165 |
new_height = (new_height // 8) * 8
|
| 166 |
-
|
| 167 |
return new_width, new_height
|
| 168 |
|
| 169 |
-
# تابع
|
| 170 |
-
def
|
| 171 |
-
if
|
| 172 |
return gr.update(visible=True), gr.update(visible=True)
|
| 173 |
else:
|
| 174 |
return gr.update(visible=False), gr.update(visible=False)
|
|
@@ -206,11 +186,9 @@ def infer(
|
|
| 206 |
if input_image is None:
|
| 207 |
return None, seed, get_error_html("لطفاً ابتدا یک تصویر بارگذاری کنید.")
|
| 208 |
|
| 209 |
-
# 1. بررسی امنیت تصویر ورودی
|
| 210 |
if is_image_nsfw(input_image):
|
| 211 |
return None, seed, get_error_html("تصویر ورودی دارای محتوای نامناسب است و پردازش نمیشود.")
|
| 212 |
|
| 213 |
-
# 2. ترجمه و بررسی متن
|
| 214 |
english_prompt = translate_prompt(prompt)
|
| 215 |
if not check_text_safety(english_prompt):
|
| 216 |
return None, seed, get_error_html("متن درخواست شامل کلمات غیرمجاز یا غیراخلاقی است.")
|
|
@@ -230,7 +208,6 @@ def infer(
|
|
| 230 |
|
| 231 |
original_image = input_image.convert("RGB")
|
| 232 |
|
| 233 |
-
# --- منطق ابعاد ---
|
| 234 |
selection_value = ASPECT_RATIOS_MAP.get(aspect_ratio_selection)
|
| 235 |
|
| 236 |
if selection_value == "Custom":
|
|
@@ -253,7 +230,6 @@ def infer(
|
|
| 253 |
true_cfg_scale=guidance_scale,
|
| 254 |
).images[0]
|
| 255 |
|
| 256 |
-
# 4. بررسی امنیت تصویر خروجی
|
| 257 |
if is_image_nsfw(result):
|
| 258 |
return None, seed, get_error_html("تصویر تولید شده حاوی محتوای نامناسب بود و حذف شد.")
|
| 259 |
|
|
@@ -264,7 +240,6 @@ def infer(
|
|
| 264 |
|
| 265 |
@spaces.GPU(duration=30)
|
| 266 |
def infer_example(input_image, prompt, lora_adapter):
|
| 267 |
-
# برای نمونهها
|
| 268 |
res, s, status = infer(input_image, prompt, lora_adapter, 0, True, 1.0, 4, "خودکار (پیشفرض)", 1024, 1024)
|
| 269 |
return res, s, status
|
| 270 |
|
|
@@ -391,6 +366,10 @@ textarea:focus, input[type="text"]:focus {
|
|
| 391 |
box-shadow: 0 8px 25px rgba(16, 185, 129, 0.45) !important;
|
| 392 |
}
|
| 393 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
#download-btn {
|
| 395 |
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
|
| 396 |
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3) !important;
|
|
@@ -434,6 +413,11 @@ textarea:focus, input[type="text"]:focus {
|
|
| 434 |
padding: 10px !important;
|
| 435 |
}
|
| 436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
footer { display: none !important; }
|
| 438 |
.flagging { display: none !important; }
|
| 439 |
|
|
@@ -485,9 +469,9 @@ with gr.Blocks() as demo:
|
|
| 485 |
lines=3
|
| 486 |
)
|
| 487 |
|
| 488 |
-
# --- اضافه کردن بخش نمایش وضعیت (پیامها) ---
|
| 489 |
status_box = gr.HTML(label="وضعیت")
|
| 490 |
-
|
|
|
|
| 491 |
run_button = gr.Button("✨ شروع پردازش و ساخت تصویر", variant="primary", elem_classes="primary-btn")
|
| 492 |
|
| 493 |
with gr.Column():
|
|
@@ -510,17 +494,15 @@ with gr.Blocks() as demo:
|
|
| 510 |
interactive=True
|
| 511 |
)
|
| 512 |
|
| 513 |
-
# اسلایدرها
|
| 514 |
-
with gr.Row():
|
| 515 |
custom_width = gr.Slider(
|
| 516 |
label="عرض دلخواه (Width)",
|
| 517 |
-
minimum=256, maximum=2048, step=8, value=1024
|
| 518 |
-
visible=False
|
| 519 |
)
|
| 520 |
custom_height = gr.Slider(
|
| 521 |
label="ارتفاع دلخواه (Height)",
|
| 522 |
-
minimum=256, maximum=2048, step=8, value=1024
|
| 523 |
-
visible=False
|
| 524 |
)
|
| 525 |
|
| 526 |
seed = gr.Slider(label="دانه تصادفی (Seed)", minimum=0, maximum=MAX_SEED, step=1, value=0)
|
|
@@ -528,11 +510,16 @@ with gr.Blocks() as demo:
|
|
| 528 |
guidance_scale = gr.Slider(label="میزان وفاداری به متن (Guidance Scale)", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
|
| 529 |
steps = gr.Slider(label="تعداد مراحل پردازش (Steps)", minimum=1, maximum=50, step=1, value=4)
|
| 530 |
|
| 531 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
aspect_ratio_selection.change(
|
| 533 |
-
fn=
|
| 534 |
inputs=aspect_ratio_selection,
|
| 535 |
-
outputs=
|
| 536 |
)
|
| 537 |
|
| 538 |
gr.Examples(
|
|
@@ -550,17 +537,18 @@ with gr.Blocks() as demo:
|
|
| 550 |
["examples/6.jpg", "دوربین را به نمای پایین به بالا تغییر بده.", "تغییر زاویه دید"],
|
| 551 |
],
|
| 552 |
inputs=[input_image, prompt, lora_adapter],
|
| 553 |
-
outputs=[output_image, seed, status_box],
|
| 554 |
fn=infer_example,
|
| 555 |
cache_examples=False,
|
| 556 |
label="نمونهها (برای تست کلیک کنید)"
|
| 557 |
)
|
| 558 |
|
| 559 |
-
# اتصال دکمه اجرا
|
| 560 |
run_button.click(
|
| 561 |
fn=infer,
|
| 562 |
inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps, aspect_ratio_selection, custom_width, custom_height],
|
| 563 |
-
outputs=[output_image, seed, status_box]
|
|
|
|
| 564 |
)
|
| 565 |
|
| 566 |
download_button.click(
|
|
|
|
| 38 |
try:
|
| 39 |
results = safety_classifier(image)
|
| 40 |
for result in results:
|
| 41 |
+
if result['label'] == 'nsfw' and result['score'] > 0.75:
|
| 42 |
return True
|
| 43 |
return False
|
| 44 |
except Exception as e:
|
|
|
|
| 67 |
).to(device)
|
| 68 |
|
| 69 |
# بارگذاری LoRA ها
|
| 70 |
+
pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime", weight_name="Qwen-Image-Edit-2509-Photo-to-Anime_000001000.safetensors", adapter_name="anime")
|
| 71 |
+
pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multiple-angles", weight_name="镜头转换.safetensors", adapter_name="multiple-angles")
|
| 72 |
+
pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Light_restoration", weight_name="移除光影.safetensors", adapter_name="light-restoration")
|
| 73 |
+
pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Relight", weight_name="Qwen-Edit-Relight.safetensors", adapter_name="relight")
|
| 74 |
+
pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multi-Angle-Lighting", weight_name="多角度灯光-251116.safetensors", adapter_name="multi-angle-lighting")
|
| 75 |
+
pipe.load_lora_weights("tlennon-ie/qwen-edit-skin", weight_name="qwen-edit-skin_1.1_000002750.safetensors", adapter_name="edit-skin")
|
| 76 |
+
pipe.load_lora_weights("lovis93/next-scene-qwen-image-lora-2509", weight_name="next-scene_lora-v2-3000.safetensors", adapter_name="next-scene")
|
| 77 |
+
pipe.load_lora_weights("vafipas663/Qwen-Edit-2509-Upscale-LoRA", weight_name="qwen-edit-enhance_64-v3_000001000.safetensors", adapter_name="upscale-image")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
|
| 80 |
MAX_SEED = np.iinfo(np.int32).max
|
|
|
|
| 133 |
def update_dimensions_on_upload(image):
|
| 134 |
if image is None:
|
| 135 |
return 1024, 1024
|
|
|
|
| 136 |
original_width, original_height = image.size
|
|
|
|
| 137 |
if original_width > original_height:
|
| 138 |
new_width = 1024
|
| 139 |
aspect_ratio = original_height / original_width
|
|
|
|
| 142 |
new_height = 1024
|
| 143 |
aspect_ratio = original_width / original_height
|
| 144 |
new_width = int(new_height * aspect_ratio)
|
|
|
|
| 145 |
new_width = (new_width // 8) * 8
|
| 146 |
new_height = (new_height // 8) * 8
|
|
|
|
| 147 |
return new_width, new_height
|
| 148 |
|
| 149 |
+
# تابع بهروزرسانی وضعیت نمایش اسلایدرها
|
| 150 |
+
def update_sliders_visibility(choice):
|
| 151 |
+
if choice == "شخصیسازی (Custom)":
|
| 152 |
return gr.update(visible=True), gr.update(visible=True)
|
| 153 |
else:
|
| 154 |
return gr.update(visible=False), gr.update(visible=False)
|
|
|
|
| 186 |
if input_image is None:
|
| 187 |
return None, seed, get_error_html("لطفاً ابتدا یک تصویر بارگذاری کنید.")
|
| 188 |
|
|
|
|
| 189 |
if is_image_nsfw(input_image):
|
| 190 |
return None, seed, get_error_html("تصویر ورودی دارای محتوای نامناسب است و پردازش نمیشود.")
|
| 191 |
|
|
|
|
| 192 |
english_prompt = translate_prompt(prompt)
|
| 193 |
if not check_text_safety(english_prompt):
|
| 194 |
return None, seed, get_error_html("متن درخواست شامل کلمات غیرمجاز یا غیراخلاقی است.")
|
|
|
|
| 208 |
|
| 209 |
original_image = input_image.convert("RGB")
|
| 210 |
|
|
|
|
| 211 |
selection_value = ASPECT_RATIOS_MAP.get(aspect_ratio_selection)
|
| 212 |
|
| 213 |
if selection_value == "Custom":
|
|
|
|
| 230 |
true_cfg_scale=guidance_scale,
|
| 231 |
).images[0]
|
| 232 |
|
|
|
|
| 233 |
if is_image_nsfw(result):
|
| 234 |
return None, seed, get_error_html("تصویر تولید شده حاوی محتوای نامناسب بود و حذف شد.")
|
| 235 |
|
|
|
|
| 240 |
|
| 241 |
@spaces.GPU(duration=30)
|
| 242 |
def infer_example(input_image, prompt, lora_adapter):
|
|
|
|
| 243 |
res, s, status = infer(input_image, prompt, lora_adapter, 0, True, 1.0, 4, "خودکار (پیشفرض)", 1024, 1024)
|
| 244 |
return res, s, status
|
| 245 |
|
|
|
|
| 366 |
box-shadow: 0 8px 25px rgba(16, 185, 129, 0.45) !important;
|
| 367 |
}
|
| 368 |
|
| 369 |
+
.primary-btn:active, button.primary:active {
|
| 370 |
+
transform: translateY(1px);
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
#download-btn {
|
| 374 |
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
|
| 375 |
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3) !important;
|
|
|
|
| 413 |
padding: 10px !important;
|
| 414 |
}
|
| 415 |
|
| 416 |
+
.gradio-container tbody td span,
|
| 417 |
+
.gradio-container tbody td p {
|
| 418 |
+
color: #374151 !important;
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
footer { display: none !important; }
|
| 422 |
.flagging { display: none !important; }
|
| 423 |
|
|
|
|
| 469 |
lines=3
|
| 470 |
)
|
| 471 |
|
|
|
|
| 472 |
status_box = gr.HTML(label="وضعیت")
|
| 473 |
+
|
| 474 |
+
# اضافه کردن api_name="predict" برای فعال کردن حالت API
|
| 475 |
run_button = gr.Button("✨ شروع پردازش و ساخت تصویر", variant="primary", elem_classes="primary-btn")
|
| 476 |
|
| 477 |
with gr.Column():
|
|
|
|
| 494 |
interactive=True
|
| 495 |
)
|
| 496 |
|
| 497 |
+
# اسلایدرها با visible=False شروع میشوند
|
| 498 |
+
with gr.Row(visible=False) as custom_dims_row:
|
| 499 |
custom_width = gr.Slider(
|
| 500 |
label="عرض دلخواه (Width)",
|
| 501 |
+
minimum=256, maximum=2048, step=8, value=1024
|
|
|
|
| 502 |
)
|
| 503 |
custom_height = gr.Slider(
|
| 504 |
label="ارتفاع دلخواه (Height)",
|
| 505 |
+
minimum=256, maximum=2048, step=8, value=1024
|
|
|
|
| 506 |
)
|
| 507 |
|
| 508 |
seed = gr.Slider(label="دانه تصادفی (Seed)", minimum=0, maximum=MAX_SEED, step=1, value=0)
|
|
|
|
| 510 |
guidance_scale = gr.Slider(label="میزان وفاداری به متن (Guidance Scale)", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
|
| 511 |
steps = gr.Slider(label="تعداد مراحل پردازش (Steps)", minimum=1, maximum=50, step=1, value=4)
|
| 512 |
|
| 513 |
+
# اصلاح منطق نمایش/مخفی کردن ردیف اسلایدرها
|
| 514 |
+
def toggle_row(choice):
|
| 515 |
+
if choice == "شخصیسازی (Custom)":
|
| 516 |
+
return gr.update(visible=True)
|
| 517 |
+
return gr.update(visible=False)
|
| 518 |
+
|
| 519 |
aspect_ratio_selection.change(
|
| 520 |
+
fn=toggle_row,
|
| 521 |
inputs=aspect_ratio_selection,
|
| 522 |
+
outputs=custom_dims_row # کنترل کل ردیف به جای تک تک اسلایدرها
|
| 523 |
)
|
| 524 |
|
| 525 |
gr.Examples(
|
|
|
|
| 537 |
["examples/6.jpg", "دوربین را به نمای پایین به بالا تغییر بده.", "تغییر زاویه دید"],
|
| 538 |
],
|
| 539 |
inputs=[input_image, prompt, lora_adapter],
|
| 540 |
+
outputs=[output_image, seed, status_box],
|
| 541 |
fn=infer_example,
|
| 542 |
cache_examples=False,
|
| 543 |
label="نمونهها (برای تست کلیک کنید)"
|
| 544 |
)
|
| 545 |
|
| 546 |
+
# اتصال دکمه اجرا با قابلیت API
|
| 547 |
run_button.click(
|
| 548 |
fn=infer,
|
| 549 |
inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps, aspect_ratio_selection, custom_width, custom_height],
|
| 550 |
+
outputs=[output_image, seed, status_box],
|
| 551 |
+
api_name="predict" # فعالسازی API
|
| 552 |
)
|
| 553 |
|
| 554 |
download_button.click(
|