import gradio as gr import numpy as np import random import spaces import torch from diffusers import DiffusionPipeline # Load the model dtype = torch.bfloat16 device = "cuda" if torch.cuda.is_available() else "cpu" pipe = DiffusionPipeline.from_pretrained("black-forest-labs/FLUX.1-schnell", torch_dtype=dtype).to(device) # Constants MAX_SEED = np.iinfo(np.int32).max MAX_IMAGE_SIZE = 2048 # Style list for prompt customization style_list = [ {"name": "D&D Art", "prompt": "dungeons & dragons style artwork {prompt}. d&d style, key visual, vibrant, studio anime, highly detailed", "negative_prompt": "photo, deformed, black and white, realism, disfigured, low contrast"}, {"name": "Dark Fantasy", "prompt": "dark and moody dungeons & dragons artwork of {prompt}. gothic ruins, shadowy figures, haunting atmospheres, grim villains, muted colors, intricate textures, sinister undertones", "negative_prompt": "bright, cheerful, cartoonish, lighthearted, futuristic, deformed"}, {"name": "Epic Battle", "prompt": "dynamic dungeons & dragons artwork of {prompt}. epic battle scene, legendary heroes, fierce monsters, intense action, dramatic lighting, high-detail environment, magical effects, vibrant colors", "negative_prompt": "peaceful, mundane, low energy, modern, sci-fi, simplistic, cartoonish, low contrast"}, # Add additional styles as needed {"name": "(No style)", "prompt": "{prompt}", "negative_prompt": ""}, ] styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list} STYLE_NAMES = list(styles.keys()) DEFAULT_STYLE_NAME = "D&D Art" # Function to apply selected style def apply_style(style_name: str, positive: str, negative: str = ""): p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME]) return p.replace("{prompt}", positive), n + (negative or "") # Inference function @spaces.GPU() def infer( prompt, style, seed=42, randomize_seed=False, width=1024, height=1024, num_inference_steps=4, progress=gr.Progress(track_tqdm=True), ): if randomize_seed: seed = random.randint(0, MAX_SEED) # Apply style to prompt styled_prompt, negative_prompt = apply_style(style, prompt) generator = torch.Generator().manual_seed(seed) image = pipe( prompt=styled_prompt, width=width, height=height, num_inference_steps=num_inference_steps, generator=generator, guidance_scale=0.0, negative_prompt=negative_prompt, ).images[0] return image, seed # Example prompts examples = [ ["A heroic adventurer wielding a flaming sword standing on a cliff", "D&D Art"], ["A mystical library with ancient scrolls and glowing runes", "Dark Fantasy"], ["A ferocious dragon breathing fire in a dark cavern", "Epic Battle"], ] # Custom CSS for a Dungeons & Dragons theme css = """ body { background-color: #1b1b1b; font-family: 'Cinzel', serif; color: #f5f5f5; background-image: url('https://www.transparenttextures.com/patterns/dark-matter.png'); } #col-container { margin: 0 auto; max-width: 550px; padding: 15px; border: 4px solid #8b4513; background: linear-gradient(145deg, #2e2b2a, #3a3433); border-radius: 15px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.8); } """ # Interface with gr.Blocks(css=css) as demo: with gr.Column(elem_id="col-container"): # Title and Description gr.Markdown( """ # 🛡️ ChatDnD.net Dungeons & Dragons Image Generator ⚔️ **Unleash Your Imagination!** Create heroes, maps, quests, and epic scenes to bring your campaigns to life. Tailored for adventurers seeking inspiration or Dungeon Masters constructing their next grand story.
[Visit Our Website](https://chatdnd.net) | [Support Us](https://buymeacoffee.com/watchoutformike) """ ) # Prompt input and style selector with gr.Row(): prompt = gr.Textbox( label="🎲 Describe Your Vision:", lines=3, placeholder="Describe your hero, monster, or legendary landscape..." ) style = gr.Dropdown( label="🎨 Select a Style", choices=STYLE_NAMES, value=DEFAULT_STYLE_NAME, ) # Run button and result display with gr.Row(): run_button = gr.Button("Generate Image") result = gr.Image(label="🖼️ Your Legendary Vision") # Advanced settings with gr.Accordion("⚙️ Advanced Settings", open=False): seed = gr.Slider( label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, ) randomize_seed = gr.Checkbox(label="Randomize Seed", value=True) with gr.Row(): width = gr.Slider( label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024, ) height = gr.Slider( label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024, ) num_inference_steps = gr.Slider( label="Inference Steps", minimum=1, maximum=50, step=1, value=4, ) # Examples with styles gr.Examples( examples=examples, inputs=[prompt, style], outputs=[result], fn=infer, cache_examples="lazy", ) # Interactivity gr.on( triggers=[run_button.click, prompt.submit], fn=infer, inputs=[prompt, style, seed, randomize_seed, width, height, num_inference_steps], outputs=[result, seed], ) # Launch the demo demo.launch()