| """ |
| ╔══════════════════════════════════════════════════════════════╗ |
| ║ ╔╦╗╦ ╦╔═╗ ═╗ ╔═╗ ║ |
| ║ ║ ╠═╣║╣ ╔╩╦╝╚═╗ ║ |
| ║ ╩ ╩ ╩╚═╝ ╩ ╚═╚═╝ ║ |
| ║ ║ |
| ║ UNLIMITED AI IMAGE GENERATION & EDITING ║ |
| ║ Uncensored • Hyper-Detailed • Professional Grade ║ |
| ╚══════════════════════════════════════════════════════════════╝ |
| """ |
|
|
| import gradio as gr |
| import torch |
| import random |
| import time |
| import os |
| from PIL import Image, ImageFilter, ImageEnhance |
| from diffusers import ( |
| FluxPipeline, |
| FluxImg2ImgPipeline, |
| FluxInpaintPipeline, |
| FluxFillPipeline, |
| StableDiffusionInstructPix2PixPipeline, |
| ) |
| import numpy as np |
|
|
| |
| MODELS = { |
| "flux_schnell": "black-forest-labs/FLUX.1-schnell", |
| "flux_dev": "black-forest-labs/FLUX.1-dev", |
| "flux_fill": "black-forest-labs/FLUX.1-Fill-dev", |
| "instruct_pix2pix": "timbrooks/instruct-pix2pix", |
| } |
|
|
| CACHED_PIPES = {} |
|
|
| |
| QUALITY_PRESETS = { |
| "⚡ Speed (4 steps)": {"steps": 4, "guidance": 0.0, "desc": "Fast preview, ~3s"}, |
| "🎯 Balanced (8 steps)": {"steps": 8, "guidance": 0.0, "desc": "Good quality, ~6s"}, |
| "💎 Quality (15 steps)": {"steps": 15, "guidance": 0.0, "desc": "High quality, ~12s"}, |
| "👑 Masterpiece (25 steps)": {"steps": 25, "guidance": 0.0, "desc": "Best quality, ~20s"}, |
| "🔮 Ultra (50 steps)": {"steps": 50, "guidance": 3.5, "desc": "Ultimate detail (dev model)"}, |
| } |
|
|
| STYLE_PRESETS = [ |
| "hyper-realistic, 8k resolution, professional photography, ultra detailed, sharp focus," |
| " cinematic lighting, masterpiece, award-winning", |
| "anime style, studio ghibli, vibrant colors, detailed background, beautiful composition", |
| "oil painting, renaissance style, dramatic lighting, textured brushstrokes, museum quality", |
| "cyberpunk, neon lights, futuristic city, blade runner aesthetic, high contrast, detailed", |
| "fantasy art, magic, ethereal, trending on artstation, digital painting, intricate details", |
| "dark gothic, moody atmosphere, chiaroscuro, dramatic shadows, horror aesthetic", |
| "minimalist, clean lines, pastel colors, modern design, elegant simplicity", |
| "photorealistic portrait, 85mm lens, f/1.4, golden hour, bokeh, professional photography", |
| "3D render, octane render, unreal engine 5, ray tracing, highly detailed textures", |
| "watercolor painting, soft edges, flowing colors, artistic, dreamy atmosphere", |
| "pencil sketch, charcoal drawing, detailed linework, artistic, monochrome", |
| "pop art, bold colors, comic style, Roy Lichtenstein inspired, halftone patterns", |
| ] |
|
|
| |
| NEGATIVE_PROMPT = ( |
| "blurry, low quality, distorted, deformed, ugly, bad anatomy, bad proportions," |
| " extra limbs, cloned face, disfigured, gross proportions, malformed limbs," |
| " missing arms, missing legs, extra arms, extra legs, fused fingers, too many fingers," |
| " long neck, watermark, signature, text, jpeg artifacts, lowres, error" |
| ) |
|
|
| |
|
|
| def get_pipe(model_key, model_id, pipeline_class, dtype=torch.bfloat16): |
| """Load/cache pipeline.""" |
| if model_key in CACHED_PIPES: |
| return CACHED_PIPES[model_key] |
|
|
| print(f"🚀 Loading {model_key}...") |
| pipe = pipeline_class.from_pretrained( |
| model_id, |
| torch_dtype=dtype, |
| ) |
| pipe.enable_model_cpu_offload() |
| |
| if hasattr(pipe, "enable_vae_slicing"): |
| pipe.enable_vae_slicing() |
| if hasattr(pipe, "enable_vae_tiling"): |
| pipe.enable_vae_tiling() |
|
|
| CACHED_PIPES[model_key] = pipe |
| print(f"✅ {model_key} loaded!") |
| return pipe |
|
|
|
|
| def enhance_image_quality(img): |
| """Post-process: enhance sharpness and contrast for hyper-detailed output.""" |
| enhancer = ImageEnhance.Sharpness(img) |
| img = enhancer.enhance(1.3) |
| enhancer = ImageEnhance.Contrast(img) |
| img = enhancer.enhance(1.1) |
| enhancer = ImageEnhance.Color(img) |
| img = enhancer.enhance(1.05) |
| return img |
|
|
|
|
| def upscale_image(img, target_size): |
| """Upscale image to target resolution using Lanczos.""" |
| w, h = img.size |
| if w >= target_size[0] and h >= target_size[1]: |
| return img |
| |
| ratio = max(target_size[0] / w, target_size[1] / h) |
| new_w = int(w * ratio) |
| new_h = int(h * ratio) |
| return img.resize((new_w, new_h), Image.LANCZOS) |
|
|
|
|
| def apply_post(img, enhance, upscale_size): |
| """Apply post-processing: enhance and/or upscale.""" |
| if enhance: |
| img = enhance_image_quality(img) |
| if upscale_size and upscale_size != "Original": |
| target_sizes = { |
| "2K (2048px)": (2048, 2048), |
| "4K (3840px)": (3840, 3840), |
| "8K (7680px)": (7680, 7680), |
| } |
| if upscale_size in target_sizes: |
| img = upscale_image(img, target_sizes[upscale_size]) |
| return img |
|
|
|
|
| |
| |
| |
|
|
| def generate_text2img( |
| prompt, |
| negative_prompt, |
| style_prompt, |
| quality_preset, |
| width, |
| height, |
| seed, |
| num_images, |
| enhance, |
| upscale_size, |
| progress=gr.Progress(), |
| ): |
| """Generate images from text prompt using FLUX.""" |
| if not prompt.strip(): |
| return [], "❌ Please enter a prompt!" |
|
|
| |
| full_prompt = prompt |
| if style_prompt and style_prompt != "None": |
| full_prompt = f"{prompt}, {style_prompt}" |
|
|
| |
| q = QUALITY_PRESETS[quality_preset] |
| is_dev = "ultra" in quality_preset.lower() or q["steps"] >= 50 |
|
|
| progress(0.1, desc="📥 Loading model...") |
|
|
| if is_dev: |
| pipe = get_pipe("flux_dev", MODELS["flux_dev"], FluxPipeline) |
| guidance = q["guidance"] |
| else: |
| pipe = get_pipe("flux_schnell", MODELS["flux_schnell"], FluxPipeline) |
| guidance = 0.0 |
|
|
| |
| results = [] |
| for i in range(num_images): |
| progress(0.2 + (0.6 * i / max(num_images, 1)), desc=f"🎨 Generating image {i+1}/{num_images}...") |
|
|
| gen_seed = seed if seed >= 0 else random.randint(0, 2**32 - 1) |
| generator = torch.Generator("cpu").manual_seed(gen_seed) |
|
|
| with torch.inference_mode(): |
| output = pipe( |
| prompt=full_prompt, |
| negative_prompt=negative_prompt if negative_prompt else NEGATIVE_PROMPT, |
| guidance_scale=guidance, |
| height=height, |
| width=width, |
| num_inference_steps=q["steps"], |
| max_sequence_length=256 if not is_dev else 512, |
| generator=generator, |
| ) |
|
|
| img = output.images[0] |
| img = apply_post(img, enhance, upscale_size) |
| results.append(img) |
|
|
| progress(1.0, desc="✅ Done!") |
| status = f"✅ Generated {num_images} image(s) | Quality: {quality_preset} | Seed: {gen_seed}" |
|
|
| return results if len(results) > 1 else results, status |
|
|
|
|
| |
| |
| |
|
|
| def edit_image_img2img( |
| input_image, |
| prompt, |
| negative_prompt, |
| style_prompt, |
| strength, |
| quality_preset, |
| seed, |
| enhance, |
| upscale_size, |
| progress=gr.Progress(), |
| ): |
| """Edit an image using prompt guidance via FLUX Img2Img.""" |
| if input_image is None: |
| return None, "❌ Please upload an image!" |
| if not prompt.strip(): |
| return None, "❌ Please enter an edit prompt!" |
|
|
| progress(0.05, desc="🖼️ Processing input image...") |
|
|
| |
| w, h = input_image.size |
| w = (w // 64) * 64 |
| h = (h // 64) * 64 |
| input_image = input_image.resize((w, h), Image.LANCZOS) |
|
|
| full_prompt = prompt |
| if style_prompt and style_prompt != "None": |
| full_prompt = f"{prompt}, {style_prompt}" |
|
|
| q = QUALITY_PRESETS[quality_preset] |
|
|
| progress(0.1, desc="📥 Loading model...") |
| pipe = get_pipe("flux_schnell_img2img", MODELS["flux_schnell"], FluxImg2ImgPipeline) |
|
|
| gen_seed = seed if seed >= 0 else random.randint(0, 2**32 - 1) |
| generator = torch.Generator("cpu").manual_seed(gen_seed) |
|
|
| progress(0.2, desc="🎨 Editing image...") |
| with torch.inference_mode(): |
| output = pipe( |
| prompt=full_prompt, |
| image=input_image, |
| strength=strength, |
| guidance_scale=0.0, |
| num_inference_steps=q["steps"], |
| generator=generator, |
| ) |
|
|
| img = output.images[0] |
| img = apply_post(img, enhance, upscale_size) |
|
|
| progress(1.0, desc="✅ Done!") |
| status = f"✅ Image edited | Strength: {strength} | Seed: {gen_seed}" |
|
|
| return img, status |
|
|
|
|
| |
| |
| |
|
|
| def edit_image_instruct( |
| input_image, |
| instruction, |
| image_cfg_scale, |
| text_cfg_scale, |
| steps, |
| seed, |
| enhance, |
| upscale_size, |
| progress=gr.Progress(), |
| ): |
| """Edit image using natural language instructions (InstructPix2Pix).""" |
| if input_image is None: |
| return None, "❌ Please upload an image!" |
| if not instruction.strip(): |
| return None, "❌ Please enter an editing instruction!" |
|
|
| progress(0.05, desc="🖼️ Processing image...") |
|
|
| |
| input_image = input_image.resize((512, 512), Image.LANCZOS) |
|
|
| progress(0.1, desc="📥 Loading InstructPix2Pix model...") |
| pipe = get_pipe( |
| "instruct_pix2pix", |
| MODELS["instruct_pix2pix"], |
| StableDiffusionInstructPix2PixPipeline, |
| dtype=torch.float16, |
| ) |
|
|
| gen_seed = seed if seed >= 0 else random.randint(0, 2**32 - 1) |
| generator = torch.Generator("cpu").manual_seed(gen_seed) |
|
|
| progress(0.2, desc="✏️ Applying edit instruction...") |
| with torch.inference_mode(): |
| output = pipe( |
| prompt=instruction, |
| image=input_image, |
| num_inference_steps=steps, |
| image_guidance_scale=image_cfg_scale, |
| guidance_scale=text_cfg_scale, |
| generator=generator, |
| ) |
|
|
| img = output.images[0] |
| img = apply_post(img, enhance, upscale_size) |
|
|
| progress(1.0, desc="✅ Done!") |
| status = f"✅ Instruction applied: '{instruction}' | Seed: {gen_seed}" |
|
|
| return img, status |
|
|
|
|
| |
| |
| |
|
|
| def handle_inpaint( |
| sketch_input, |
| prompt, |
| style_prompt, |
| quality_preset, |
| seed, |
| enhance, |
| upscale_size, |
| progress=gr.Progress(), |
| ): |
| """Handle inpaint from sketch component (dict with 'image' and 'mask' keys).""" |
| if sketch_input is None: |
| return None, "❌ Please upload an image and draw a mask!" |
|
|
| |
| if isinstance(sketch_input, dict): |
| input_image = sketch_input.get("image") |
| mask_image = sketch_input.get("mask") |
| else: |
| |
| input_image = sketch_input |
| mask_image = None |
|
|
| if input_image is None: |
| return None, "❌ Please upload an image!" |
| if mask_image is None: |
| return None, "❌ Please draw a mask on the image!" |
| if not prompt.strip(): |
| return None, "❌ Please describe what to generate in the masked area!" |
|
|
| full_prompt = prompt |
| if style_prompt and style_prompt != "None": |
| full_prompt = f"{prompt}, {style_prompt}" |
|
|
| q = QUALITY_PRESETS[quality_preset] |
|
|
| |
| w, h = input_image.size |
| new_w = (w // 64) * 64 |
| new_h = (h // 64) * 64 |
| input_image = input_image.resize((new_w, new_h), Image.LANCZOS) |
| mask_image = mask_image.resize((new_w, new_h), Image.LANCZOS) |
|
|
| progress(0.1, desc="📥 Loading FLUX Fill model...") |
| pipe = get_pipe("flux_fill", MODELS["flux_fill"], FluxFillPipeline) |
|
|
| gen_seed = seed if seed >= 0 else random.randint(0, 2**32 - 1) |
| generator = torch.Generator("cpu").manual_seed(gen_seed) |
|
|
| progress(0.2, desc="🖌️ Inpainting masked area...") |
| with torch.inference_mode(): |
| output = pipe( |
| prompt=full_prompt, |
| image=input_image, |
| mask_image=mask_image, |
| height=new_h, |
| width=new_w, |
| guidance_scale=30.0, |
| num_inference_steps=q["steps"], |
| max_sequence_length=512, |
| generator=generator, |
| ) |
|
|
| img = output.images[0] |
| img = apply_post(img, enhance, upscale_size) |
|
|
| progress(1.0, desc="✅ Done!") |
| status = f"✅ Inpainting complete | Seed: {gen_seed}" |
|
|
| return img, status |
|
|
|
|
| |
| |
| |
|
|
| def upscale_standalone( |
| input_image, |
| target_size, |
| enhance, |
| progress=gr.Progress(), |
| ): |
| """Standalone upscaler with enhancement.""" |
| if input_image is None: |
| return None, "❌ Please upload an image!" |
|
|
| progress(0.1, desc="🔍 Upscaling...") |
|
|
| target_sizes = { |
| "2K (2048px)": (2048, 2048), |
| "4K (3840px)": (3840, 3840), |
| "8K (7680px)": (7680, 7680), |
| } |
| size = target_sizes.get(target_size, (2048, 2048)) |
| img = upscale_image(input_image, size) |
|
|
| if enhance: |
| progress(0.7, desc="✨ Enhancing...") |
| img = enhance_image_quality(img) |
|
|
| progress(1.0, desc="✅ Done!") |
| status = f"✅ Upscaled to {target_size} | Output: {img.size[0]}x{img.size[1]}px" |
|
|
| return img, status |
|
|
|
|
| |
| |
| |
|
|
| CSS = """ |
| :root { |
| --bg: #0a0a0f; |
| --card: #12121a; |
| --border: #1e1e30; |
| --accent: #7c3aed; |
| --accent2: #a855f7; |
| --text: #e2e8f0; |
| --text-muted: #94a3b8; |
| --gradient: linear-gradient(135deg, #7c3aed, #db2777); |
| } |
| body { background: var(--bg) !important; } |
| .gradio-container { max-width: 1400px !important; margin: 0 auto !important; } |
| #thex-header { |
| text-align: center; |
| padding: 2rem 1rem 1rem 1rem; |
| background: var(--gradient); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| background-clip: text; |
| font-size: 3.5rem; |
| font-weight: 900; |
| letter-spacing: 0.05em; |
| margin-bottom: 0; |
| font-family: 'Segoe UI', system-ui, sans-serif; |
| } |
| #thex-subtitle { |
| text-align: center; |
| color: var(--text-muted); |
| font-size: 1.1rem; |
| margin-top: -0.5rem; |
| letter-spacing: 0.15em; |
| text-transform: uppercase; |
| } |
| .tab-nav { |
| background: var(--card) !important; |
| border: 1px solid var(--border) !important; |
| border-radius: 12px !important; |
| } |
| button { |
| background: var(--accent) !important; |
| color: white !important; |
| border: none !important; |
| border-radius: 8px !important; |
| font-weight: 600 !important; |
| transition: all 0.2s !important; |
| } |
| button:hover { |
| background: var(--accent2) !important; |
| transform: translateY(-1px); |
| box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4); |
| } |
| .gr-form, .gr-box { |
| background: var(--card) !important; |
| border: 1px solid var(--border) !important; |
| border-radius: 12px !important; |
| } |
| .gr-input, .gr-text-input textarea, input[type="text"] { |
| background: #0a0a0f !important; |
| border: 1px solid var(--border) !important; |
| color: var(--text) !important; |
| border-radius: 8px !important; |
| } |
| label { |
| color: var(--text) !important; |
| font-weight: 500 !important; |
| } |
| .gr-panel { border: none !important; } |
| footer { display: none !important; } |
| """ |
|
|
| with gr.Blocks( |
| css=CSS, |
| title="The-X | Unlimited AI Image Studio", |
| theme=gr.themes.Soft(), |
| ) as demo: |
| |
| gr.HTML( |
| """ |
| <h1 id="thex-header">╔╦╗╦ ╦╔═╗ ═╗ ╔═╗</h1> |
| <p id="thex-subtitle">UNLIMITED AI IMAGE GENERATION & EDITING • UNCENSORED • 8K QUALITY</p> |
| """ |
| ) |
|
|
| with gr.Tabs() as tabs: |
| |
| |
| |
| with gr.TabItem("🎨 Text-to-Image", id="txt2img"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| prompt_input = gr.Textbox( |
| label="✨ Your Prompt", |
| placeholder="Describe the image you want to create in vivid detail...\n\nExample: A majestic dragon perched on a crystalline mountain peak, wings spread, breathing ethereal blue fire into a stormy sky, hyper-realistic, 8k, cinematic lighting, volumetric fog, intricate scales", |
| lines=5, |
| ) |
| with gr.Accordion("🎭 Style Presets", open=False): |
| style_dropdown = gr.Dropdown( |
| choices=["None"] + STYLE_PRESETS, |
| value="hyper-realistic, 8k resolution, professional photography, ultra detailed, sharp focus, cinematic lighting, masterpiece, award-winning", |
| label="Style Template", |
| ) |
| neg_prompt = gr.Textbox( |
| label="🚫 Negative Prompt", |
| value=NEGATIVE_PROMPT, |
| lines=2, |
| ) |
|
|
| with gr.Row(): |
| quality_preset = gr.Radio( |
| choices=list(QUALITY_PRESETS.keys()), |
| value="⚡ Speed (4 steps)", |
| label="⚡ Quality Preset", |
| ) |
| with gr.Row(): |
| width = gr.Slider(256, 1280, value=1024, step=64, label="Width") |
| height = gr.Slider(256, 1280, value=1024, step=64, label="Height") |
| with gr.Row(): |
| seed = gr.Number(value=-1, label="🎲 Seed (-1 = random)", precision=0) |
| num_images = gr.Slider(1, 4, value=1, step=1, label="📸 Images") |
| with gr.Row(): |
| enhance_cb = gr.Checkbox(value=True, label="✨ Auto-enhance quality") |
| upscale_dd = gr.Dropdown( |
| choices=["Original", "2K (2048px)", "4K (3840px)", "8K (7680px)"], |
| value="Original", |
| label="🔍 Upscale output", |
| ) |
| generate_btn = gr.Button("🎨 GENERATE", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| output_gallery = gr.Gallery( |
| label="Generated Images", |
| columns=2, |
| rows=2, |
| height=600, |
| object_fit="contain", |
| ) |
| status_t2i = gr.Textbox(label="Status", interactive=False) |
|
|
| generate_btn.click( |
| fn=generate_text2img, |
| inputs=[ |
| prompt_input, neg_prompt, style_dropdown, quality_preset, |
| width, height, seed, num_images, enhance_cb, upscale_dd, |
| ], |
| outputs=[output_gallery, status_t2i], |
| ) |
|
|
| |
| |
| |
| with gr.TabItem("🖼️ Prompt Edit (Img2Img)", id="img2img"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| img2img_input = gr.Image(label="📤 Upload Image", type="pil", height=400) |
| img2img_prompt = gr.Textbox( |
| label="✏️ Edit Prompt", |
| placeholder="Describe how you want to transform this image...\n\nExample: turn this into a neon cyberpunk scene, add glowing holograms, futuristic city background", |
| lines=3, |
| ) |
| with gr.Accordion("🎭 Style Presets", open=False): |
| img2img_style = gr.Dropdown( |
| choices=["None"] + STYLE_PRESETS, |
| value="None", |
| label="Style Template", |
| ) |
| img2img_neg = gr.Textbox(label="🚫 Negative Prompt", value=NEGATIVE_PROMPT, lines=2) |
| img2img_strength = gr.Slider(0.1, 1.0, value=0.75, step=0.05, label="🔥 Transformation Strength") |
| img2img_quality = gr.Radio( |
| choices=list(QUALITY_PRESETS.keys()), |
| value="💎 Quality (15 steps)", |
| label="⚡ Quality Preset", |
| ) |
| with gr.Row(): |
| img2img_seed = gr.Number(value=-1, label="🎲 Seed") |
| img2img_enhance = gr.Checkbox(value=True, label="✨ Enhance") |
| img2img_upscale = gr.Dropdown( |
| choices=["Original", "2K (2048px)", "4K (3840px)", "8K (7680px)"], |
| value="Original", |
| label="🔍 Upscale", |
| ) |
| img2img_btn = gr.Button("🖼️ TRANSFORM IMAGE", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| img2img_output = gr.Image(label="✨ Edited Image", type="pil", height=500) |
| img2img_status = gr.Textbox(label="Status", interactive=False) |
|
|
| img2img_btn.click( |
| fn=edit_image_img2img, |
| inputs=[ |
| img2img_input, img2img_prompt, img2img_neg, img2img_style, |
| img2img_strength, img2img_quality, img2img_seed, |
| img2img_enhance, img2img_upscale, |
| ], |
| outputs=[img2img_output, img2img_status], |
| ) |
|
|
| |
| |
| |
| with gr.TabItem("📝 Instruct Edit (AI-Powered)", id="instruct"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| instruct_input = gr.Image(label="📤 Upload Image", type="pil", height=400) |
| instruct_prompt = gr.Textbox( |
| label="🗣️ Natural Language Instruction", |
| placeholder="Tell the AI what to change in plain English...\n\nExamples:\n• 'Make the sky sunset orange'\n• 'Turn this into a watercolor painting'\n• 'Add snow on the mountains'\n• 'Make the person smile'\n• 'Change the background to a beach'", |
| lines=3, |
| ) |
| with gr.Row(): |
| instruct_img_cfg = gr.Slider(1.0, 3.0, value=1.5, step=0.1, label="Image Faithfulness") |
| instruct_text_cfg = gr.Slider(1.0, 15.0, value=7.5, step=0.5, label="Instruction Strength") |
| with gr.Row(): |
| instruct_steps = gr.Slider(10, 100, value=50, step=5, label="Quality Steps") |
| instruct_seed = gr.Number(value=-1, label="🎲 Seed") |
| with gr.Row(): |
| instruct_enhance = gr.Checkbox(value=True, label="✨ Enhance") |
| instruct_upscale = gr.Dropdown( |
| choices=["Original", "2K (2048px)", "4K (3840px)", "8K (7680px)"], |
| value="Original", |
| label="🔍 Upscale", |
| ) |
| instruct_btn = gr.Button("🤖 APPLY INSTRUCTION", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| instruct_output = gr.Image(label="✨ Edited Image", type="pil", height=500) |
| instruct_status = gr.Textbox(label="Status", interactive=False) |
|
|
| instruct_btn.click( |
| fn=edit_image_instruct, |
| inputs=[ |
| instruct_input, instruct_prompt, instruct_img_cfg, |
| instruct_text_cfg, instruct_steps, instruct_seed, |
| instruct_enhance, instruct_upscale, |
| ], |
| outputs=[instruct_output, instruct_status], |
| ) |
|
|
| |
| |
| |
| with gr.TabItem("🖌️ Inpaint (Draw & Fill)", id="inpaint"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| inpaint_sketch = gr.Image( |
| label="📤 Upload Image & Draw Mask", |
| type="pil", |
| tool="sketch", |
| height=400, |
| ) |
| gr.HTML("<p style='color:#94a3b8;font-size:0.85rem;margin-top:-10px;'>✏️ <b>Draw</b> on the image to create a mask, then describe what to fill</p>") |
| inpaint_prompt = gr.Textbox( |
| label="🎨 What to generate in the masked area", |
| placeholder="Describe what should appear inside the drawn mask...", |
| lines=2, |
| ) |
| with gr.Accordion("🎭 Style Presets", open=False): |
| inpaint_style = gr.Dropdown( |
| choices=["None"] + STYLE_PRESETS, |
| value="None", |
| label="Style", |
| ) |
| inpaint_quality = gr.Radio( |
| choices=list(QUALITY_PRESETS.keys()), |
| value="💎 Quality (15 steps)", |
| label="⚡ Quality Preset", |
| ) |
| with gr.Row(): |
| inpaint_seed = gr.Number(value=-1, label="🎲 Seed") |
| inpaint_enhance = gr.Checkbox(value=True, label="✨ Enhance") |
| inpaint_upscale = gr.Dropdown( |
| choices=["Original", "2K (2048px)", "4K (3840px)", "8K (7680px)"], |
| value="Original", |
| label="🔍 Upscale", |
| ) |
| inpaint_btn = gr.Button("🖌️ INPAINT", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| inpaint_output = gr.Image(label="✨ Inpainted Image", type="pil", height=500) |
| inpaint_status = gr.Textbox(label="Status", interactive=False) |
|
|
| inpaint_btn.click( |
| fn=handle_inpaint, |
| inputs=[ |
| inpaint_sketch, inpaint_prompt, inpaint_style, |
| inpaint_quality, inpaint_seed, inpaint_enhance, inpaint_upscale, |
| ], |
| outputs=[inpaint_output, inpaint_status], |
| ) |
|
|
| |
| |
| |
| with gr.TabItem("🔍 Upscaler (8K)", id="upscaler"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| upscale_input = gr.Image(label="📤 Upload Image", type="pil", height=400) |
| upscale_target = gr.Radio( |
| choices=["2K (2048px)", "4K (3840px)", "8K (7680px)"], |
| value="4K (3840px)", |
| label="📐 Target Resolution", |
| ) |
| upscale_enhance = gr.Checkbox(value=True, label="✨ Auto-enhance sharpness & contrast") |
| upscale_btn = gr.Button("🔍 UPSCALE", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| upscale_output = gr.Image(label="✨ Upscaled Image", type="pil", height=500) |
| upscale_status = gr.Textbox(label="Status", interactive=False) |
|
|
| upscale_btn.click( |
| fn=upscale_standalone, |
| inputs=[upscale_input, upscale_target, upscale_enhance], |
| outputs=[upscale_output, upscale_status], |
| ) |
|
|
| |
| gr.HTML( |
| """ |
| <div style="text-align:center; padding:2rem; color:#64748b; font-size:0.85rem;"> |
| <p>⚡ <b>The-X</b> — Powered by FLUX.1 • Uncensored • No content filters • No safety checkers</p> |
| <p style="margin-top:0.5rem;">All generated content is your responsibility. Use wisely. 🎨</p> |
| </div> |
| """ |
| ) |
|
|
| |
| if __name__ == "__main__": |
| demo.queue(max_size=10).launch(server_name="0.0.0.0", server_port=7860) |