spxxtu commited on
Commit
c00567f
·
verified ·
1 Parent(s): a34d56f

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +193 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import io
4
+ from PIL import Image
5
+
6
+ # ── Models ──────────────────────────────────────────────────────────────────
7
+ MODELS = {
8
+ "⚡ FLUX Schnell (fastest)": "black-forest-labs/FLUX.1-schnell",
9
+ "🎨 SDXL Base (high quality)": "stabilityai/stable-diffusion-xl-base-1.0",
10
+ "🖼 SD 1.5 (classic)": "runwayml/stable-diffusion-v1-5",
11
+ "🌅 Openjourney (Midjourney style)": "prompthero/openjourney-v4",
12
+ }
13
+
14
+ # ── Style presets ────────────────────────────────────────────────────────────
15
+ STYLES = {
16
+ "None": "",
17
+ "Cinematic": ", cinematic lighting, film grain, anamorphic lens, dramatic shadows",
18
+ "Anime": ", anime style, vibrant colors, studio ghibli, detailed illustration",
19
+ "Oil Painting": ", oil painting, textured brushstrokes, classical art, museum quality",
20
+ "Neon Noir": ", neon noir, rain-slicked streets, cyberpunk, moody atmosphere",
21
+ "Soft Dream": ", soft focus, dreamy, pastel tones, ethereal, bokeh",
22
+ "Raw Photo": ", photorealistic, RAW photo, DSLR, 85mm lens, sharp focus",
23
+ }
24
+
25
+ # ── Aspect ratios ────────────────────────────────────────────────────────────
26
+ RATIOS = {
27
+ "1:1 (512×512)": (512, 512),
28
+ "3:2 (768×512)": (768, 512),
29
+ "2:3 (512×768)": (512, 768),
30
+ "16:9 (896×512)": (896, 512),
31
+ }
32
+
33
+ HF_API = "https://api-inference.huggingface.co/models/"
34
+
35
+ # ─────────────────────────────────────────────────────────────────────────────
36
+
37
+ def generate(
38
+ hf_token: str,
39
+ prompt: str,
40
+ negative_prompt: str,
41
+ model_label: str,
42
+ style_label: str,
43
+ ratio_label: str,
44
+ steps: int,
45
+ guidance: float,
46
+ ):
47
+ if not hf_token.strip():
48
+ raise gr.Error("🔑 Please enter your Hugging Face API token.")
49
+ if not prompt.strip():
50
+ raise gr.Error("✏️ Please enter a prompt.")
51
+
52
+ model_id = MODELS[model_label]
53
+ style_tag = STYLES[style_label]
54
+ width, height = RATIOS[ratio_label]
55
+ full_prompt = prompt + style_tag
56
+
57
+ headers = {"Authorization": f"Bearer {hf_token.strip()}"}
58
+ payload = {"inputs": full_prompt}
59
+
60
+ # FLUX Schnell doesn't support guidance_scale / negative_prompt
61
+ if "FLUX" in model_label:
62
+ payload["parameters"] = {
63
+ "num_inference_steps": steps,
64
+ "width": width,
65
+ "height": height,
66
+ }
67
+ else:
68
+ payload["parameters"] = {
69
+ "negative_prompt": negative_prompt,
70
+ "num_inference_steps": steps,
71
+ "guidance_scale": guidance,
72
+ "width": width,
73
+ "height": height,
74
+ }
75
+
76
+ response = requests.post(HF_API + model_id, headers=headers, json=payload, timeout=120)
77
+
78
+ if response.status_code == 503:
79
+ raise gr.Error("⏳ Model is loading — wait ~20 seconds then try again.")
80
+ if not response.ok:
81
+ try:
82
+ detail = response.json().get("error", response.text)
83
+ except Exception:
84
+ detail = response.text
85
+ raise gr.Error(f"API error {response.status_code}: {detail}")
86
+
87
+ image = Image.open(io.BytesIO(response.content))
88
+ return image, full_prompt
89
+
90
+
91
+ # ── UI ───────────────────────────────────────────────────────────────────────
92
+
93
+ css = """
94
+ #title { text-align: center; margin-bottom: 4px; }
95
+ #sub { text-align: center; color: #888; margin-bottom: 24px; }
96
+ footer { display: none !important; }
97
+ """
98
+
99
+ with gr.Blocks(title="dreamforge · AI Image Generator", css=css, theme=gr.themes.Default(
100
+ primary_hue="yellow",
101
+ neutral_hue="slate",
102
+ font=gr.themes.GoogleFont("Syne"),
103
+ )) as demo:
104
+
105
+ gr.Markdown("# ✦ dreamforge", elem_id="title")
106
+ gr.Markdown("AI image generation powered by Hugging Face", elem_id="sub")
107
+
108
+ with gr.Row():
109
+ # ── Left column: controls ──────────────────────────────────────────
110
+ with gr.Column(scale=1):
111
+ hf_token = gr.Textbox(
112
+ label="🔑 Hugging Face Token",
113
+ placeholder="hf_xxxxxxxxxxxxxxxxxxxxxxxx",
114
+ type="password",
115
+ info="Get yours free at huggingface.co/settings/tokens",
116
+ )
117
+
118
+ prompt = gr.Textbox(
119
+ label="✏️ Prompt",
120
+ placeholder="A misty mountain at golden hour, oil on canvas…",
121
+ lines=4,
122
+ )
123
+
124
+ negative_prompt = gr.Textbox(
125
+ label="🚫 Negative Prompt",
126
+ value="blurry, low quality, watermark, text, ugly, deformed",
127
+ lines=2,
128
+ )
129
+
130
+ model_label = gr.Radio(
131
+ label="🤖 Model",
132
+ choices=list(MODELS.keys()),
133
+ value=list(MODELS.keys())[0],
134
+ )
135
+
136
+ with gr.Row():
137
+ style_label = gr.Dropdown(
138
+ label="🎨 Style Preset",
139
+ choices=list(STYLES.keys()),
140
+ value="None",
141
+ )
142
+ ratio_label = gr.Dropdown(
143
+ label="📐 Aspect Ratio",
144
+ choices=list(RATIOS.keys()),
145
+ value="1:1 (512×512)",
146
+ )
147
+
148
+ with gr.Row():
149
+ steps = gr.Slider(
150
+ label="Steps",
151
+ minimum=1, maximum=50, step=1, value=4,
152
+ info="More steps = more detail (slower)"
153
+ )
154
+ guidance = gr.Slider(
155
+ label="Guidance Scale",
156
+ minimum=1.0, maximum=20.0, step=0.5, value=7.5,
157
+ info="How closely to follow the prompt"
158
+ )
159
+
160
+ generate_btn = gr.Button("✦ Generate", variant="primary", size="lg")
161
+
162
+ # ── Right column: output ───────────────────────────────────────────
163
+ with gr.Column(scale=1):
164
+ output_image = gr.Image(
165
+ label="Generated Image",
166
+ type="pil",
167
+ height=520,
168
+ )
169
+ used_prompt = gr.Textbox(
170
+ label="Full prompt sent to model",
171
+ interactive=False,
172
+ lines=2,
173
+ )
174
+
175
+ # ── Examples ──────────────────────────────────────────────────────────
176
+ gr.Examples(
177
+ examples=[
178
+ ["", "A lone astronaut on a coral reef planet, bioluminescent sea creatures, epic scale", "", "⚡ FLUX Schnell (fastest)", "Cinematic", "1:1 (512×512)", 4, 7.5],
179
+ ["", "Portrait of a Victorian explorer, oil paint, dramatic candlelight", "", "🎨 SDXL Base (high quality)", "Oil Painting", "2:3 (512×768)", 30, 8.0],
180
+ ["", "Neon-lit Tokyo alley at 3am, rain reflections, cat sitting on a barrel", "", "🖼 SD 1.5 (classic)", "Neon Noir", "3:2 (768×512)", 20, 7.5],
181
+ ],
182
+ inputs=[hf_token, prompt, negative_prompt, model_label, style_label, ratio_label, steps, guidance],
183
+ label="✨ Example Prompts",
184
+ )
185
+
186
+ generate_btn.click(
187
+ fn=generate,
188
+ inputs=[hf_token, prompt, negative_prompt, model_label, style_label, ratio_label, steps, guidance],
189
+ outputs=[output_image, used_prompt],
190
+ )
191
+
192
+ if __name__ == "__main__":
193
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=4.0.0
2
+ requests
3
+ Pillow