Spaces:
Paused
Paused
File size: 4,816 Bytes
8124057 37abfc2 55c7101 4d78f82 55c7101 b574e01 e074d8e b574e01 e074d8e 38d816c 37abfc2 55c7101 37abfc2 55c7101 37abfc2 55c7101 37abfc2 b574e01 6e52c0e b574e01 55c7101 b574e01 55c7101 b574e01 0a10f4f 37abfc2 55c7101 37abfc2 a218b7f d3a3bf1 6e52c0e 2aa608d 6e52c0e 55c7101 e074d8e 2aa608d e074d8e 0d5ecb1 d3a3bf1 52b4e6d 4d78f82 2aa608d b574e01 2aa608d b574e01 4d78f82 b574e01 4d78f82 55c7101 4d78f82 55c7101 4d78f82 38d816c d3a3bf1 2aa608d 4d78f82 8124057 37abfc2 55c7101 37abfc2 55c7101 4d78f82 55c7101 4d78f82 55c7101 4d78f82 55c7101 4d78f82 55c7101 4d78f82 55c7101 4d78f82 55c7101 8124057 2aa608d 55c7101 2aa608d b574e01 2aa608d 64855f6 55c7101 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
import gradio as gr
from PIL import Image
import torch
import os
import json
import zipfile
from datetime import datetime
from diffusers import StableDiffusionXLImg2ImgPipeline
from utils.planner import (
extract_scene_plan,
generate_prompt_variations_from_scene,
generate_negative_prompt_from_scene
)
# ----------------------------
# π» Device Configuration
# ----------------------------
device = "cuda" if torch.cuda.is_available() else "cpu"
dtype = torch.float16 if device == "cuda" else torch.float32
# ----------------------------
# π§ Load Stable Diffusion XL Img2Img Pipeline
# ----------------------------
pipe = StableDiffusionXLImg2ImgPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=dtype,
use_safetensors=True,
variant="fp16" if device == "cuda" else None,
)
pipe.to(device)
if device == "cuda":
pipe.enable_model_cpu_offload()
pipe.enable_attention_slicing()
# ----------------------------
# π¨ Core Generation Function
# ----------------------------
def process_image(prompt, image, num_variations):
try:
if image is None:
raise ValueError("π« Please upload an image.")
print("π§ Prompt received:", prompt)
scene_plan = extract_scene_plan(prompt, image)
enriched_prompts = generate_prompt_variations_from_scene(scene_plan, prompt, num_variations)
negative_prompt = generate_negative_prompt_from_scene(scene_plan)
image = image.resize((1024, 1024)).convert("RGB")
outputs = []
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
out_dir = f"outputs/session_{timestamp}"
os.makedirs(out_dir, exist_ok=True)
for i, enriched_prompt in enumerate(enriched_prompts):
print(f"β¨ Generating Image {i + 1}...")
result = pipe(
prompt=enriched_prompt,
negative_prompt=negative_prompt,
image=image,
strength=0.7,
guidance_scale=7.5,
num_inference_steps=30,
)
output_img = result.images[0]
output_img.save(f"{out_dir}/generated_{i+1}.png")
outputs.append(output_img)
# Save log
log_data = {
"timestamp": timestamp,
"prompt": prompt,
"scene_plan": scene_plan,
"enriched_prompts": enriched_prompts,
"negative_prompt": negative_prompt,
"device": device,
"num_variations": num_variations
}
os.makedirs("logs", exist_ok=True)
with open("logs/generation_logs.jsonl", "a") as log_file:
log_file.write(json.dumps(log_data) + "\n")
# Create ZIP of outputs
# Handle single or multiple image download
if num_variations == 1:
single_img_path = f"{out_dir}/generated_1.png"
return outputs, "β
Generated one image. Ready for download.", single_img_path
else:
zip_path = f"{out_dir}/all_images.zip"
with zipfile.ZipFile(zip_path, "w") as zipf:
for i in range(len(outputs)):
img_path = f"{out_dir}/generated_{i+1}.png"
zipf.write(img_path, os.path.basename(img_path))
return outputs, f"β
Generated {num_variations} images. Download below.", zip_path
except Exception as e:
print("β Generation failed:", e)
return [Image.new("RGB", (512, 512), color="red")], f"β Error: {str(e)}", None
# ----------------------------
# π§ͺ Gradio Interface
# ----------------------------
with gr.Blocks(title="NewCrux Image-to-Image Generator") as demo:
gr.Markdown("### πΌοΈ NewCrux: Product Lifestyle Visual Generator (SDXL + Prompt AI)\nUpload a product image and describe the visual you want. The system will generate realistic marketing images using AI.")
with gr.Row():
prompt = gr.Textbox(label="Prompt", placeholder="e.g., A person running on the beach wearing the product")
input_image = gr.Image(type="pil", label="Product Image")
num_outputs = gr.Slider(1, 5, value=3, step=1, label="Number of Variations")
generate_btn = gr.Button("π Generate Image(s)")
output_gallery = gr.Gallery(label="Generated Images", show_label=True, columns=[2], height="auto")
output_msg = gr.Textbox(label="Generation Status", interactive=False)
download_zip = gr.File(label="β¬οΈ Download All Images (.zip)", interactive=False)
generate_btn.click(
fn=process_image,
inputs=[prompt, input_image, num_outputs],
outputs=[output_gallery, output_msg, download_zip]
)
# ----------------------------
# π Launch App
# ----------------------------
if __name__ == "__main__":
demo.launch()
|