Spaces:
Running
Running
| import gradio as gr | |
| import os | |
| from pathlib import Path | |
| from utils import setup_repository, run_inference | |
| # Ensure output directory exists | |
| OUTPUT_DIR = Path("output_minecraft_skins") | |
| OUTPUT_DIR.mkdir(parents=True, exist_ok=True) | |
| # Custom CSS for Minecraft pixelated look and checkered background | |
| CUSTOM_CSS = """ | |
| .pixelated { image-rendering: pixelated; image-rendering: -moz-crisp-edges; image-rendering: crisp-edges; } | |
| .checkered { | |
| background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect fill="%23ddd" width="8" height="8"/><rect fill="%23ddd" x="8" y="8" width="8" height="8"/><rect fill="%23bbb" x="8" width="8" height="8"/><rect fill="%23bbb" y="8" width="8" height="8"/></svg>'); | |
| background-size: 16px; | |
| } | |
| #mc-skin { max-width: 400px; margin: auto; } | |
| #mc-model { height: 500px; } | |
| .sidebar { background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); } | |
| """ | |
| def random_seed(): | |
| """Generate a random seed.""" | |
| import numpy as np | |
| return np.random.randint(0, np.iinfo(np.int32).max) | |
| def clear_all(): | |
| """Clear all outputs.""" | |
| return None, None, gr.Gallery(visible=False), [] | |
| with gr.Blocks( | |
| title="Minecraft Skin Generator", | |
| theme=gr.themes.Soft(primary_hue="green", secondary_hue="emerald"), | |
| css=CUSTOM_CSS, | |
| fill_height=True | |
| ) as demo: | |
| gr.Markdown( | |
| """ | |
| # π Minecraft Skin Generator | |
| **Built with [anycoder](https://huggingface.co/spaces/akhaliq/anycoder)** | |
| Make AI generated Minecraft Skins using finetuned Stable Diffusion models! π¨π¨βπΌ | |
| [GitHub Repo](https://github.com/BF667/Minecraft_Skin_Generator) | [Discord](https://discord.gg/AQsmBmgEPy) | |
| """ | |
| ) | |
| gr.Markdown( | |
| """ | |
| Credits: [Monadical-SAS](https://github.com/Monadical-SAS/minecraft_skin_generator), [Nick088](https://linktr.ee/Nick088), and more! | |
| """ | |
| ) | |
| state = gr.State(value=[]) # For gallery history | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| with gr.Accordion("ποΈ Generation Settings", open=True): | |
| prompt = gr.Textbox( | |
| label="Prompt", | |
| placeholder="e.g., steve with diamond armor, cyberpunk creeper", | |
| lines=2, | |
| scale=3 | |
| ) | |
| with gr.Row(): | |
| model_dropdown = gr.Dropdown( | |
| choices=["xl", "2"], | |
| value="xl", | |
| label="Model", | |
| info="XL understands prompts better" | |
| ) | |
| precision_dropdown = gr.Dropdown( | |
| choices=["fp16", "fp32"], | |
| value="fp16", | |
| label="Precision" | |
| ) | |
| with gr.Row(): | |
| steps_slider = gr.Slider(1, 50, value=25, step=1, label="Inference Steps") | |
| guidance_slider = gr.Slider(0.0, 10.0, value=7.5, step=0.1, label="Guidance Scale") | |
| with gr.Row(): | |
| seed_slider = gr.Slider(0, 2147483647, value=42, step=1, label="Seed", interactive=True) | |
| random_btn = gr.Button("π² Random Seed", scale=0, min_width=120) | |
| filename_tb = gr.Textbox("output-skin.png", label="Filename (.png)", interactive=True) | |
| gen_btn = gr.Button("Generate Skin! π", variant="primary", scale=2) | |
| adv_cb = gr.CheckboxGroup( | |
| choices=["3D Model", "Verbose"], | |
| label="Advanced Options", | |
| value=["3D Model"] | |
| ) | |
| gr.Examples( | |
| examples=[ | |
| ["steve with diamond armor"], | |
| ["alex as cyberpunk hacker"], | |
| ["creeper with sunglasses"], | |
| ["enderman in space suit"], | |
| ["zombie knight armor"] | |
| ], | |
| inputs=prompt | |
| ) | |
| gr.Markdown("### π± Cool Features") | |
| gr.Markdown(""" | |
| - **Pixelated Minecraft Style** preview | |
| - **3D Model Viewer** with rotations | |
| - **Random Seed** for variety | |
| - **History Gallery** of generations | |
| - **Batch Mode** coming soon! | |
| """) | |
| with gr.Column(scale=2): | |
| with gr.Group(elem_classes="checkered"): | |
| skin_img = gr.Image( | |
| label="Generated Skin", | |
| elem_id="mc-skin", | |
| elem_classes="pixelated" | |
| ) | |
| model_3d = gr.Model3D( | |
| label="3D Preview", | |
| clear_color=[0.1, 0.2, 0.3, 1.0], | |
| elem_id="mc-model" | |
| ) | |
| gallery = gr.Gallery( | |
| label="Generation History", | |
| columns=3, | |
| height=300, | |
| visible=True | |
| ) | |
| # Events | |
| random_btn.click(random_seed, outputs=seed_slider) | |
| gen_btn.click( | |
| fn=run_inference, | |
| inputs=[ | |
| prompt, | |
| model_dropdown, | |
| steps_slider, | |
| guidance_slider, | |
| precision_dropdown, | |
| seed_slider, | |
| filename_tb, | |
| gr.State(lambda x: "3D Model" in x)(adv_cb), | |
| gr.State(lambda x: "Verbose" in x)(adv_cb) | |
| ], | |
| outputs=[skin_img, model_3d], | |
| api_name="generate_skin", | |
| api_visibility="public", | |
| show_progress="full" | |
| ).then( | |
| fn=lambda img_path, history: (history + [img_path] if img_path else history)[:12], | |
| inputs=[skin_img, state], | |
| outputs=[gallery, state] | |
| ) | |
| # Clear button | |
| gr.ClearButton([prompt, skin_img, model_3d, gallery, state], value="ποΈ Clear All") | |
| # Examples click | |
| gr.Examples( | |
| examples=[ | |
| ["steve with diamond armor"], | |
| ["alex as cyberpunk hacker"], | |
| ["creeper with sunglasses"], | |
| ["enderman in space suit"], | |
| ["zombie knight armor"] | |
| ], | |
| inputs=[prompt], | |
| examples_per_page=5, | |
| run_on_click=True | |
| ) | |
| # Setup repo on load | |
| demo.load(setup_repository) | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True, | |
| footer_links=[ | |
| {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}, | |
| "api", | |
| "gradio" | |
| ] | |
| ) |