import gradio as gr import random import os from PIL import Image, ImageDraw, ImageFont import textwrap import torch import spaces device = "cuda" if torch.cuda.is_available() else "cpu" @spaces.GPU(enable_queue=True) def load_pipeline(): from diffusers import AutoPipelineForImage2Image pipe = AutoPipelineForImage2Image.from_pretrained( "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16 if device == "cuda" else torch.float32, variant="fp16" if device == "cuda" else None, use_safetensors=True, ) if device == "cuda": pipe.enable_model_cpu_offload() return pipe pipe = load_pipeline() # ====================== HELPERS ====================== def list_files(prefix): return [f for f in os.listdir(".") if f.startswith(prefix) and f.lower().endswith((".png", ".jpg", ".jpeg"))] def get_random_base(): bases = list_files("saint_base_") return Image.open(random.choice(bases)).convert("RGB") if bases else Image.new("RGB", (512, 512), "#2a0d4a") def create_saint_card(generated_img: Image.Image, saint_name: str, chaotic_sin: str): frames = list_files("frame_") frame_path = frames[0] if frames else None if frame_path: frame = Image.open(frame_path).convert("RGBA") else: frame = Image.new("RGBA", (800, 1000), (42, 13, 74, 255)) # Adjust these numbers so the photo sits perfectly inside your frame inner_x, inner_y, inner_w, inner_h = 90, 140, 620, 620 saint_resized = generated_img.resize((inner_w, inner_h), Image.Resampling.LANCZOS) frame.paste(saint_resized, (inner_x, inner_y)) draw = ImageDraw.Draw(frame) try: font_big = ImageFont.truetype("FONT.ttf", 62) font_med = ImageFont.truetype("FONT.ttf", 44) font_small = ImageFont.truetype("FONT.ttf", 34) except: font_big = font_med = font_small = ImageFont.load_default() draw.text((130, 55), saint_name.upper(), font=font_big, fill="#f5c242", stroke_width=6, stroke_fill="#2a0d4a") draw.text((150, 740), chaotic_sin.upper(), font=font_med, fill="#ffd700", stroke_width=4, stroke_fill="#2a0d4a") draw.text((200, 860), "STILL HAS TO CONFESS", font=font_small, fill="#ffffff", stroke_width=3, stroke_fill="#2a0d4a") draw.text((280, 905), "HOLY SMOKES", font=font_small, fill="#f5c242", stroke_width=3, stroke_fill="#2a0d4a") return frame def create_oracle_card(saint_name: str, chaotic_sin: str, vibe: str, accessory: str): width, height = 620, 860 parchment = Image.new("RGB", (width, height), "#f5e8c7") draw = ImageDraw.Draw(parchment) draw.rectangle((25, 25, width-25, height-25), outline="#d4a017", width=24) draw.rectangle((45, 45, width-45, height-45), outline="#2a0d4a", width=10) try: font_title = ImageFont.truetype("FONT.ttf", 44) font_body = ImageFont.truetype("FONT.ttf", 29) font_banner = ImageFont.truetype("FONT.ttf", 34) except: font_title = font_body = font_banner = ImageFont.load_default() prayer = f"""Prayer to {saint_name} the Unbothered Oh {saint_name}, 3 a.m. comeback daily. Bless me with {accessory} as my dignity's grease and that unbothered face slays. Edges snatched, receipts gone because of {chaotic_sin}. Werk. Amen. ✨""" draw.text((width//2, 90), "Prayer to", font=font_title, fill="#2a0d4a", anchor="mm") draw.text((width//2, 145), f"{saint_name} the Unbothered", font=font_title, fill="#2a0d4a", anchor="mm") wrapped = textwrap.fill(prayer.split("\n\n")[1], width=34) draw.text((72, 230), wrapped, font=font_body, fill="#2a0d4a", spacing=8) draw.text((width//2, height - 95), "STILL HAS TO CONFESS", font=font_banner, fill="#d4a017", anchor="mm") draw.text((width//2, height - 52), "HOLY SMOKES", font=font_banner, fill="#d4a017", anchor="mm") return parchment @spaces.GPU def canonize(photo, saint_name, chaotic_sin, divine_vibe, sacred_accessory, drama, debauch, delulu): if not saint_name: saint_name = "Santa Vibra Raro" if not chaotic_sin: chaotic_sin = "Still has to confess" init_image = photo.convert("RGB") if photo is not None else get_random_base() prompt = (f"tarot card style portrait of Saint {saint_name}, {divine_vibe.lower()}, " f"holding {sacred_accessory.lower()}, ethereal holy glow, dramatic lighting, masterpiece") negative = "blurry, ugly, deformed, extra limbs, bad anatomy, low quality" strength = 0.35 + (delulu * 0.065) guidance = 6.0 + (drama * 1.5) steps = 18 + (debauch * 5) result = pipe( prompt=prompt, image=init_image, strength=strength, guidance_scale=guidance, num_inference_steps=steps, negative_prompt=negative, ).images[0] saint_card = create_saint_card(result, saint_name, chaotic_sin) oracle_card = create_oracle_card(saint_name, chaotic_sin, divine_vibe, sacred_accessory) return saint_card, oracle_card # ====================== GRADIO UI WITH GALAXY LOOK ====================== with gr.Blocks( title="HOLY SMOKES SAINTIFIER", theme=gr.themes.Dark(), css=""" body { background: radial-gradient(circle at center, #2a0d4a 0%, #000022 70%, #000011 100%) !important; } .gradio-container { background: transparent !important; } .phone-frame { background: #111; border-radius: 55px; padding: 18px; box-shadow: 0 0 60px rgba(245,194,66,0.7), inset 0 0 30px rgba(255,255,255,0.1); max-width: 360px; margin: 20px auto; } """ ) as demo: gr.HTML("""
Upload chaos → Get canonized 🔥