File size: 6,048 Bytes
59442a5 9220236 171a55d 0a5d622 9220236 69d087d 9220236 171a55d 9220236 69d087d 9220236 59442a5 171a55d 59442a5 69d087d 8ea4751 59442a5 69d087d 171a55d 59442a5 9220236 59442a5 171a55d 59442a5 171a55d 59442a5 0a5d622 69d087d 9220236 69d087d 171a55d 9220236 69d087d 171a55d 69d087d 9220236 69d087d 9220236 59442a5 69d087d 9220236 69d087d 171a55d 69d087d 9220236 69d087d 9220236 69d087d 8ea4751 9220236 8ea4751 9220236 69d087d 9220236 69d087d 171a55d 9220236 8ea4751 69d087d 8ea4751 9220236 8ea4751 9220236 59442a5 0a5d622 8ea4751 0a5d622 59442a5 8ea4751 927bff0 8ea4751 0a5d622 59442a5 c228ca0 8ea4751 0a5d622 59442a5 69d087d 59442a5 9220236 59442a5 69d087d 59442a5 9220236 | 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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | import os
import io
import zipfile
import sys
import traceback
import time
import tempfile
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
# --- DEBUG SETUP ---
sys.stdout.flush()
print("=== APP STARTING UP ===")
print(f"Current Working Directory: {os.getcwd()}")
print(f"Python Version: {sys.version}")
# CRITICAL FIX: Catch import errors
try:
import cv2
import numpy as np
from PIL import Image
from rembg import remove, new_session
from huggingface_hub import InferenceClient
import gradio as gr
print("All libraries imported successfully.")
except Exception as e:
print("CRITICAL IMPORT ERROR:", e)
print(traceback.format_exc())
sys.exit(1)
# Get your HF Token
HF_TOKEN = os.getenv("HF_TOKEN")
if not HF_TOKEN:
print("WARNING: HF_TOKEN environment variable is NOT SET. AI Backgrounds will fail.")
else:
print("HF_TOKEN found.")
client = InferenceClient(token=HF_TOKEN)
# Preload the rembg model
print("Loading rembg model... (this takes ~20 seconds)")
try:
session = new_session()
print("rembg model loaded successfully!")
except Exception as e:
print("ERROR loading rembg model:", e)
print(traceback.format_exc())
session = None
def enhance_lighting(pil_img):
try:
cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
lab = cv2.cvtColor(cv_img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
l = clahe.apply(l)
lab = cv2.merge([l, a, b])
cv_img = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
return Image.fromarray(cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB))
except Exception as e:
print(f"Lighting fix failed: {e}")
return pil_img
def fix_aspect_ratio(pil_img, ratio_str):
w, h = pil_img.size
ratio_map = {"1:1": 1.0, "4:5": 0.8, "16:9": 1.777}
target_r = ratio_map[ratio_str]
current_r = w / h
if current_r > target_r:
new_w = int(h * target_r)
pil_img = pil_img.crop(((w - new_w)//2, 0, (w + new_w)//2, h))
else:
new_h = int(w / target_r)
pil_img = pil_img.crop((0, (h - new_h)//2, w, (h + new_h)//2))
return pil_img
def process_batch(files, ratio, rm_bg, prompt):
processed = []
# Check if files is None or empty
if not files:
return "❌ Error: No files uploaded. Please upload at least one image."
# Loop through all uploaded files
for idx, file in enumerate(files):
try:
print(f"--- Processing image {idx+1} of {len(files)} ---")
start_time = time.time()
# 1. Open the image
img = Image.open(file).convert("RGB")
print(f"Image opened. Size: {img.size}")
# 2. Fix Lighting
img = enhance_lighting(img)
# 3. Fix Aspect Ratio
img = fix_aspect_ratio(img, ratio)
# 4. Remove Background
if rm_bg:
if session is None:
raise Exception("rembg model failed to load during startup. Check Space Logs.")
print("Running rembg...")
img = remove(img, session=session)
print("rembg completed.")
# 5. Generate AI Background
if prompt and rm_bg:
print(f"Generating AI background for prompt: {prompt}")
# --- FIXED MODEL HERE ---
bg_img = client.text_to_image(
f"Product photography background of {prompt}, elegant, soft studio light, photorealistic, 8k",
model="black-forest-labs/FLUX.1-dev" # Updated model
)
bg_img = bg_img.resize(img.size).convert("RGBA")
final = bg_img.copy()
final.paste(img, (0, 0), img)
img = final
print("AI background composited.")
processed.append(img)
print(f"Image {idx+1} finished in {time.time() - start_time:.2f} seconds.")
except Exception as e:
# --- FIXED ERROR HANDLER ---
error_msg = f"❌ ERROR on image {idx+1} ('{file.name}'):\n{str(e)}"
print(error_msg)
print(traceback.format_exc())
# Return the error as a string directly to the UI
return error_msg
# --- FINAL RETURN LOGIC ---
if not processed:
return None
# Create a temporary directory
temp_dir = tempfile.mkdtemp()
zip_path = os.path.join(temp_dir, "jewelry_processed.zip")
# Write the ZIP file to disk with PNG compression
with zipfile.ZipFile(zip_path, "w") as zf:
for i, img in enumerate(processed):
buff = io.BytesIO()
# PNG compression
if img.width > 3000 or img.height > 3000:
img.thumbnail((3000, 3000), Image.LANCZOS)
img.save(buff, format="PNG", compress_level=9)
buff.seek(0)
zf.writestr(f"jewelry_processed_{i+1}.png", buff.getvalue())
# Return the absolute file path string
return zip_path
# Gradio UI
with gr.Blocks(title="Jewelry Batch Processor") as demo:
gr.Markdown("## ✨ Free Jewelry Batch Processor")
with gr.Row():
files = gr.Files(label="Upload Jewelry Images", file_count="multiple")
ratio = gr.Dropdown(choices=["1:1", "4:5", "16:9"], value="1:1", label="Aspect Ratio")
with gr.Row():
rm_bg = gr.Checkbox(label="Remove Background", value=True)
prompt = gr.Textbox(label="AI Background Prompt (leave empty to skip)")
btn = gr.Button("🚀 Process Batch", variant="primary")
output = gr.File(label="Download Processed ZIP")
btn.click(process_batch, inputs=[files, ratio, rm_bg, prompt], outputs=output)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860) |