import spaces import gradio as gr import torch from PIL import Image from transformers import AutoProcessor from longcat_image.models import LongCatImageTransformer2DModel from longcat_image.pipelines import LongCatImageEditPipeline, LongCatImagePipeline import numpy as np # 1. DEFINE THE CUSTOM THEME CLASS (Fixed: Removing invalid keys) class AppleStyleTheme(gr.themes.Base): def __init__( self, # Core Colors: Apple uses a specific blue, crisp grays, and clean white primary_hue=gr.themes.colors.blue, secondary_hue=gr.themes.colors.gray, neutral_hue=gr.themes.colors.neutral, # Core Sizing: Larger radius for that "iOS Card" look radius_size=gr.themes.sizes.radius_lg, # Core Fonts: System fonts are key for the Apple feel font=["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"], font_mono=gr.themes.GoogleFont("IBM Plex Mono"), spacing_size=gr.themes.sizes.spacing_lg, text_size=gr.themes.sizes.text_md, **kwargs ): super().__init__( primary_hue=primary_hue, secondary_hue=secondary_hue, neutral_hue=neutral_hue, radius_size=radius_size, font=font, font_mono=font_mono, spacing_size=spacing_size, text_size=text_size, **kwargs ) # Use .set() to modify specific variables. # Removed 'tabs_border_color' which caused the error. self.set( # Global Backgrounds body_background_fill="*neutral_50", block_background_fill="white", # Block (Card) Styles - Clean, thin borders, no deep shadows block_border_color="*neutral_200", block_border_width="1px", block_shadow="none", # Primary Button Styles (The "Apple Blue" button) button_primary_background_fill="*primary_600", button_primary_background_fill_hover="*primary_500", button_primary_text_color="white", button_primary_border_color="*primary_600", # Input Styles input_background_fill="*neutral_50", input_border_color="*neutral_200", input_shadow="none", input_shadow_focus="0 0 0 2px *primary_200", ) # Instantiate the theme apple_theme = AppleStyleTheme() # --- Model Loading --- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # Text-to-Image Model t2i_model_id = 'meituan-longcat/LongCat-Image' print(f"🔄 Loading Text-to-Image model from {t2i_model_id}...") t2i_text_processor = AutoProcessor.from_pretrained( t2i_model_id, subfolder='tokenizer' ) t2i_transformer = LongCatImageTransformer2DModel.from_pretrained( t2i_model_id, subfolder='transformer', torch_dtype=torch.bfloat16, use_safetensors=True ).to(device) t2i_pipe = LongCatImagePipeline.from_pretrained( t2i_model_id, transformer=t2i_transformer, text_processor=t2i_text_processor, ) t2i_pipe.to(device, torch.bfloat16) print(f"✅ Text-to-Image model loaded successfully") # Image Edit Model edit_model_id = 'meituan-longcat/LongCat-Image-Edit' print(f"🔄 Loading Image Edit model from {edit_model_id}...") edit_text_processor = AutoProcessor.from_pretrained( edit_model_id, subfolder='tokenizer' ) edit_transformer = LongCatImageTransformer2DModel.from_pretrained( edit_model_id, subfolder='transformer', torch_dtype=torch.bfloat16, use_safetensors=True ).to(device) edit_pipe = LongCatImageEditPipeline.from_pretrained( edit_model_id, transformer=edit_transformer, text_processor=edit_text_processor, ) edit_pipe.to(device, torch.bfloat16) print(f"✅ Image Edit model loaded successfully on {device}") # --- Core Functions --- @spaces.GPU(duration=120) def generate_image( prompt: str, width: int, height: int, seed: int, progress=gr.Progress() ): """Generate image from text prompt""" if not prompt or prompt.strip() == "": raise gr.Error("Please enter a prompt") try: progress(0.1, desc="Preparing generation...") progress(0.2, desc="Generating image...") generator = torch.Generator("cuda" if torch.cuda.is_available() else "cpu").manual_seed(seed) with torch.inference_mode(): output = t2i_pipe( prompt, negative_prompt="", height=height, width=width, guidance_scale=4.5, num_inference_steps=50, num_images_per_prompt=1, generator=generator, enable_cfg_renorm=True, enable_prompt_rewrite=True ) progress(1.0, desc="Done!") return output.images[0] except Exception as e: raise gr.Error(f"Error during image generation: {str(e)}") @spaces.GPU(duration=120) def edit_image( input_image: Image.Image, prompt: str, seed: int, progress=gr.Progress() ): """Edit image based on text prompt""" if input_image is None: raise gr.Error("Please upload an image first") if not prompt or prompt.strip() == "": raise gr.Error("Please enter an edit instruction") try: progress(0.1, desc="Preparing image...") if input_image.mode != 'RGB': input_image = input_image.convert('RGB') progress(0.2, desc="Generating edited image...") generator = torch.Generator("cuda" if torch.cuda.is_available() else "cpu").manual_seed(seed) with torch.inference_mode(): output = edit_pipe( input_image, prompt, negative_prompt="", guidance_scale=4.5, num_inference_steps=50, num_images_per_prompt=1, generator=generator ) progress(1.0, desc="Done!") return output.images[0] except Exception as e: raise gr.Error(f"Error during image editing: {str(e)}") # --- Examples --- edit_example_image_url = "https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.png" edit_example_data = [ [edit_example_image_url, "Add a mustache", 42], ] t2i_example_prompts = [ ["一个年轻的亚裔女性,身穿黄色针织衫,搭配白色项链。她的双手放在膝盖上,表情恬静。背景是一堵粗糙的砖墙,午后的阳光温暖地洒在她身上,营造出一种宁静而温馨的氛围。", 1344, 768, 43], ["A serene mountain landscape at sunset with golden clouds", 1344, 768, 42], ["A cute robot sitting at a desk, digital art style", 1024, 1024, 44], ] # Build Gradio interface # Pass theme=apple_theme here. fill_width=True ensures it expands horizontally. with gr.Blocks(fill_width=True) as demo: gr.HTML("""
AI-powered image generation and editing
Powered by LongCat • Built with anycoder