Dax451 commited on
Commit
f1ebcf1
·
1 Parent(s): a6df975

Aggiunti file dell'applicazione FLUX Image Generator

Browse files
Files changed (4) hide show
  1. .gitignore +31 -0
  2. README.md +46 -14
  3. app.py +280 -141
  4. requirements.txt +4 -6
.gitignore ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Environment variables
7
+ .env
8
+ .env.*
9
+
10
+ # Virtual environments
11
+ venv/
12
+ env/
13
+ ENV/
14
+
15
+ # Distribution / packaging
16
+ dist/
17
+ build/
18
+ *.egg-info/
19
+
20
+ # Logs
21
+ *.log
22
+
23
+ # IDE specific files
24
+ .idea/
25
+ .vscode/
26
+ *.swp
27
+ *.swo
28
+
29
+ # OS specific files
30
+ .DS_Store
31
+ Thumbs.db
README.md CHANGED
@@ -1,14 +1,46 @@
1
- ---
2
- title: Flux Image Generator
3
- emoji: 🖼
4
- colorFrom: purple
5
- colorTo: red
6
- sdk: gradio
7
- sdk_version: 5.0.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- short_description: 'Generatore di immagini basato sul modello FLUX.1-schnell di '
12
- ---
13
-
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FLUX Nineteen.ai Image Generator
2
+
3
+ Generatore di immagini che utilizza l'API di Nineteen.ai con il modello FLUX.1-schnell, offrendo un'interfaccia grafica intuitiva per la creazione di immagini di alta qualità.
4
+
5
+ ## Caratteristiche
6
+
7
+ - Interfaccia utente semplice e intuitiva
8
+ - Supporto per prompt negativi
9
+ - Controllo completo sui parametri di generazione
10
+ - Esempi di prompt preconfigurati
11
+ - Autenticazione per proteggere l'accesso
12
+
13
+ ## Utilizzo
14
+
15
+ 1. Inserisci un prompt descrittivo nella casella di testo
16
+ 2. Configura i parametri di generazione secondo le tue preferenze:
17
+ - Modello: Scegli tra FLUX.1-schnell o FLUX.1-dev
18
+ - Passi di inferenza: Più passi = più dettagli (ma più lento)
19
+ - Guidance Scale: Controlla quanto l'immagine aderisce al prompt
20
+ - Dimensioni: Imposta l'altezza e la larghezza dell'immagine
21
+ 3. Opzionalmente, aggiungi un prompt negativo per escludere elementi indesiderati
22
+ 4. Clicca su "Genera Immagine"
23
+
24
+ ## Esempi di Prompt
25
+
26
+ L'applicazione include alcuni esempi di prompt ottimizzati per FLUX.1-schnell. Clicca su uno degli esempi per utilizzarlo come punto di partenza.
27
+
28
+ ## Requisiti
29
+
30
+ - Python 3.8+
31
+ - Gradio
32
+ - Requests
33
+ - Pillow
34
+ - Python-dotenv
35
+
36
+ ## Configurazione
37
+
38
+ L'applicazione utilizza le seguenti variabili d'ambiente:
39
+
40
+ - `NINETEEN_API_KEY`: La tua chiave API per Nineteen.ai
41
+ - `GRADIO_USERNAME`: Username per l'autenticazione
42
+ - `GRADIO_PASSWORD`: Password per l'autenticazione
43
+
44
+ ## Crediti
45
+
46
+ Sviluppato da Utente utilizzando l'API di Nineteen.ai e il modello FLUX.1-schnell di Black Forest Labs.
app.py CHANGED
@@ -1,154 +1,293 @@
1
- import gradio as gr
2
- import numpy as np
3
- import random
4
-
5
- # import spaces #[uncomment to use ZeroGPU]
6
- from diffusers import DiffusionPipeline
7
- import torch
8
-
9
- device = "cuda" if torch.cuda.is_available() else "cpu"
10
- model_repo_id = "stabilityai/sdxl-turbo" # Replace to the model you would like to use
11
-
12
- if torch.cuda.is_available():
13
- torch_dtype = torch.float16
14
- else:
15
- torch_dtype = torch.float32
16
-
17
- pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype)
18
- pipe = pipe.to(device)
19
-
20
- MAX_SEED = np.iinfo(np.int32).max
21
- MAX_IMAGE_SIZE = 1024
22
-
23
-
24
- # @spaces.GPU #[uncomment to use ZeroGPU]
25
- def infer(
26
- prompt,
27
- negative_prompt,
28
- seed,
29
- randomize_seed,
30
- width,
31
- height,
32
- guidance_scale,
33
- num_inference_steps,
34
- progress=gr.Progress(track_tqdm=True),
35
- ):
36
- if randomize_seed:
37
- seed = random.randint(0, MAX_SEED)
38
-
39
- generator = torch.Generator().manual_seed(seed)
40
-
41
- image = pipe(
42
- prompt=prompt,
43
- negative_prompt=negative_prompt,
44
- guidance_scale=guidance_scale,
45
- num_inference_steps=num_inference_steps,
46
- width=width,
47
- height=height,
48
- generator=generator,
49
- ).images[0]
50
-
51
- return image, seed
52
-
53
-
54
- examples = [
55
- "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k",
56
- "An astronaut riding a green horse",
57
- "A delicious ceviche cheesecake slice",
58
- ]
59
-
60
- css = """
61
- #col-container {
62
- margin: 0 auto;
63
- max-width: 640px;
64
- }
65
  """
 
 
 
 
 
66
 
67
- with gr.Blocks(css=css) as demo:
68
- with gr.Column(elem_id="col-container"):
69
- gr.Markdown(" # Text-to-Image Gradio Template")
70
-
71
- with gr.Row():
72
- prompt = gr.Text(
73
- label="Prompt",
74
- show_label=False,
75
- max_lines=1,
76
- placeholder="Enter your prompt",
77
- container=False,
78
- )
79
 
80
- run_button = gr.Button("Run", scale=0, variant="primary")
 
 
 
 
 
 
 
81
 
82
- result = gr.Image(label="Result", show_label=False)
 
83
 
84
- with gr.Accordion("Advanced Settings", open=False):
85
- negative_prompt = gr.Text(
86
- label="Negative prompt",
87
- max_lines=1,
88
- placeholder="Enter a negative prompt",
89
- visible=False,
90
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
- seed = gr.Slider(
93
- label="Seed",
94
- minimum=0,
95
- maximum=MAX_SEED,
96
- step=1,
97
- value=0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  )
99
-
100
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
101
-
102
- with gr.Row():
103
- width = gr.Slider(
104
- label="Width",
105
- minimum=256,
106
- maximum=MAX_IMAGE_SIZE,
107
- step=32,
108
- value=1024, # Replace with defaults that work for your model
 
 
 
 
109
  )
110
-
111
- height = gr.Slider(
112
- label="Height",
113
- minimum=256,
114
- maximum=MAX_IMAGE_SIZE,
115
- step=32,
116
- value=1024, # Replace with defaults that work for your model
117
  )
118
-
119
- with gr.Row():
120
- guidance_scale = gr.Slider(
121
- label="Guidance scale",
122
- minimum=0.0,
123
- maximum=10.0,
124
- step=0.1,
125
- value=0.0, # Replace with defaults that work for your model
126
- )
127
-
128
- num_inference_steps = gr.Slider(
129
- label="Number of inference steps",
130
- minimum=1,
131
- maximum=50,
132
- step=1,
133
- value=2, # Replace with defaults that work for your model
134
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
- gr.Examples(examples=examples, inputs=[prompt])
137
- gr.on(
138
- triggers=[run_button.click, prompt.submit],
139
- fn=infer,
140
- inputs=[
141
- prompt,
142
- negative_prompt,
143
- seed,
144
- randomize_seed,
145
- width,
146
- height,
147
- guidance_scale,
148
- num_inference_steps,
149
- ],
150
- outputs=[result, seed],
151
- )
 
 
 
 
 
 
 
 
152
 
153
  if __name__ == "__main__":
154
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
+ FLUX Image Generator - Nineteen.ai API (Versione HF Spaces)
3
+ --------------------------------------
4
+ Questo script utilizza l'API di Nineteen.ai per generare immagini
5
+ con il modello FLUX.1-schnell, offrendo un'interfaccia grafica intuitiva.
6
+ Versione ottimizzata per Hugging Face Spaces con autenticazione.
7
 
8
+ Autore: Utente
9
+ Data: 09/03/2025
10
+ """
 
 
 
 
 
 
 
 
 
11
 
12
+ import os
13
+ import io
14
+ import time
15
+ import base64
16
+ import requests
17
+ import gradio as gr
18
+ from PIL import Image
19
+ from dotenv import load_dotenv
20
 
21
+ # Carica le variabili d'ambiente (se presenti)
22
+ load_dotenv()
23
 
24
+ class FluxNineteenGenerator:
25
+ """
26
+ Classe per generare immagini utilizzando il modello FLUX.1-schnell
27
+ attraverso l'API di Nineteen.ai.
28
+ """
29
+
30
+ def __init__(self):
31
+ """
32
+ Inizializza il generatore di immagini FLUX tramite API Nineteen.ai.
33
+ """
34
+ print("Inizializzazione del generatore di immagini FLUX Nineteen.ai...")
35
+
36
+ # Ottieni l'API key da variabile d'ambiente o usa quella predefinita
37
+ self.api_key = os.getenv("NINETEEN_API_KEY", "rayon_6nzcBRzaq8f7iRzFUX2IsscMBGKgmJcO")
38
+
39
+ # Configurazione dell'API
40
+ self.api_endpoint = "https://api.nineteen.ai/v1/text-to-image"
41
+ self.headers = {
42
+ "Authorization": f"Bearer {self.api_key}",
43
+ "accept": "application/json",
44
+ "Content-Type": "application/json"
45
+ }
46
+
47
+ # Modelli disponibili
48
+ self.models = ["black-forest-labs/FLUX.1-schnell", "black-forest-labs/FLUX.1-dev"]
49
+ self.default_model = "black-forest-labs/FLUX.1-schnell"
50
+
51
+ print(f"Generatore inizializzato con modello predefinito: {self.default_model}")
52
+
53
+ def generate_image(self, prompt, model=None, steps=8, cfg_scale=3,
54
+ height=1024, width=1024, negative_prompt=""):
55
+ """
56
+ Genera un'immagine utilizzando l'API di Nineteen.ai.
57
+
58
+ Args:
59
+ prompt (str): Descrizione testuale dell'immagine da generare
60
+ model (str, optional): Modello da utilizzare
61
+ steps (int): Numero di passi di inferenza
62
+ cfg_scale (float): Scala di guidance per la generazione
63
+ height (int): Altezza dell'immagine in pixel
64
+ width (int): Larghezza dell'immagine in pixel
65
+ negative_prompt (str): Prompt negativo per escludere elementi indesiderati
66
+
67
+ Returns:
68
+ PIL.Image: L'immagine generata
69
+ str: Messaggio di stato
70
+ """
71
+ if not model:
72
+ model = self.default_model
73
+
74
+ try:
75
+ # Prepara il payload
76
+ data = {
77
+ "prompt": prompt,
78
+ "model": model,
79
+ "steps": steps,
80
+ "cfg_scale": cfg_scale,
81
+ "height": height,
82
+ "width": width,
83
+ "negativePrompt": negative_prompt
84
+ }
85
+
86
+ # Log della richiesta
87
+ print(f"Generazione immagine con prompt: '{prompt}'")
88
+ print(f"Parametri: modello={model}, steps={steps}, cfg_scale={cfg_scale}, dimensioni={width}x{height}")
89
+
90
+ # Effettua la chiamata API
91
+ start_time = time.time()
92
+ response = requests.post(self.api_endpoint, headers=self.headers, json=data)
93
+ end_time = time.time()
94
+
95
+ # Gestione degli errori
96
+ if response.status_code != 200:
97
+ error_message = f"Errore API: {response.status_code} - {response.text}"
98
+ print(error_message)
99
+ return None, error_message
100
+
101
+ # Estrai l'immagine in formato base64 dalla risposta
102
+ try:
103
+ image_b64 = response.json()["image_b64"]
104
+ image_data = base64.b64decode(image_b64)
105
+ image = Image.open(io.BytesIO(image_data))
106
+
107
+ print(f"Immagine generata in {end_time - start_time:.2f} secondi")
108
+ return image, f"Immagine generata in {end_time - start_time:.2f} secondi"
109
+ except KeyError:
110
+ return None, f"Errore: La risposta API non contiene il campo 'image_b64'. Risposta: {response.json()}"
111
+ except Exception as e:
112
+ return None, f"Errore nel decodificare l'immagine: {str(e)}"
113
+
114
+ except Exception as e:
115
+ error_message = f"Errore durante la generazione dell'immagine: {str(e)}"
116
+ print(error_message)
117
+ return None, error_message
118
 
119
+ def create_ui(generator):
120
+ """
121
+ Crea l'interfaccia utente Gradio.
122
+
123
+ Args:
124
+ generator (FluxNineteenGenerator): Istanza del generatore
125
+
126
+ Returns:
127
+ gradio.Interface: L'interfaccia Gradio
128
+ """
129
+
130
+ def generate_image_ui(prompt, model, steps, cfg_scale, height, width, negative_prompt):
131
+ """Funzione per generare immagini dall'interfaccia"""
132
+ # Validazione dei parametri
133
+ if not prompt or len(prompt.strip()) == 0:
134
+ return None, "Il prompt non può essere vuoto."
135
+
136
+ try:
137
+ # Converti i parametri al tipo corretto
138
+ steps = int(steps)
139
+ cfg_scale = float(cfg_scale)
140
+ height = int(height)
141
+ width = int(width)
142
+
143
+ # Validazione dei valori
144
+ if steps < 1 or steps > 50:
145
+ return None, "Il numero di passi deve essere compreso tra 1 e 50."
146
+ if cfg_scale < 1 or cfg_scale > 30:
147
+ return None, "La guidance scale deve essere compresa tra 1 e 30."
148
+ if height < 512 or height > 1536:
149
+ return None, "L'altezza deve essere compresa tra 512 e 1536 pixel."
150
+ if width < 512 or width > 1536:
151
+ return None, "La larghezza deve essere compresa tra 512 e 1536 pixel."
152
+
153
+ # Genera l'immagine
154
+ return generator.generate_image(
155
+ prompt=prompt,
156
+ model=model,
157
+ steps=steps,
158
+ cfg_scale=cfg_scale,
159
+ height=height,
160
+ width=width,
161
+ negative_prompt=negative_prompt
162
  )
163
+ except Exception as e:
164
+ return None, f"Errore: {str(e)}"
165
+
166
+ # Crea i componenti dell'interfaccia
167
+ with gr.Blocks(title="FLUX Nineteen.ai Image Generator") as interface:
168
+ gr.Markdown("# FLUX Nineteen.ai Image Generator")
169
+ gr.Markdown("Genera immagini utilizzando il modello FLUX.1-schnell tramite l'API di Nineteen.ai")
170
+
171
+ with gr.Row():
172
+ with gr.Column(scale=3):
173
+ prompt_input = gr.Textbox(
174
+ label="Prompt",
175
+ placeholder="Descrivi l'immagine che desideri generare...",
176
+ lines=3
177
  )
178
+
179
+ negative_prompt_input = gr.Textbox(
180
+ label="Prompt Negativo (opzionale)",
181
+ placeholder="Elementi da escludere dall'immagine...",
182
+ lines=2
 
 
183
  )
184
+
185
+ model_input = gr.Dropdown(
186
+ generator.models,
187
+ label="Modello",
188
+ value=generator.default_model
 
 
 
 
 
 
 
 
 
 
 
189
  )
190
+
191
+ with gr.Row():
192
+ steps_input = gr.Slider(
193
+ minimum=1,
194
+ maximum=50,
195
+ value=8,
196
+ step=1,
197
+ label="Passi di Inferenza"
198
+ )
199
+ cfg_input = gr.Slider(
200
+ minimum=1.0,
201
+ maximum=30.0,
202
+ value=3.0,
203
+ step=0.1,
204
+ label="Guidance Scale (CFG)"
205
+ )
206
+
207
+ with gr.Row():
208
+ height_input = gr.Slider(
209
+ minimum=512,
210
+ maximum=1536,
211
+ value=1024,
212
+ step=64,
213
+ label="Altezza (px)"
214
+ )
215
+ width_input = gr.Slider(
216
+ minimum=512,
217
+ maximum=1536,
218
+ value=1024,
219
+ step=64,
220
+ label="Larghezza (px)"
221
+ )
222
+
223
+ generate_button = gr.Button("Genera Immagine", variant="primary")
224
+
225
+ with gr.Column(scale=4):
226
+ output_image = gr.Image(label="Immagine Generata", type="pil")
227
+ output_status = gr.Textbox(label="Stato", interactive=False)
228
+
229
+ # Esempi di prompt
230
+ with gr.Accordion("Esempi di Prompt", open=False):
231
+ gr.Markdown("""
232
+ ### Esempi di prompt ottimizzati per FLUX.1-schnell
233
+
234
+ Clicca su uno degli esempi per utilizzarlo:
235
+ """)
236
+
237
+ examples = [
238
+ ["A breathtaking view of the Dolomites at sunrise, golden light illuminating the jagged peaks, morning mist rising from the valley below, ultra-detailed, cinematic, 8K resolution, photorealistic"],
239
+ ["Futuristic Tokyo cityscape at night, neon lights reflecting on wet streets after rain, towering skyscrapers with holographic advertisements, flying vehicles, photorealistic, cinematic lighting, 8K"],
240
+ ["Portrait of a weathered old fisherman with deep wrinkles and piercing blue eyes, wearing a cable-knit sweater, salt and pepper beard, golden hour lighting, ultra-detailed skin texture, photorealistic"],
241
+ ["Massive space station orbiting Jupiter, with Earth visible in the distance, detailed mechanical structures, solar panels, docking bays with spacecraft, photorealistic, NASA quality, 8K"],
242
+ ["Bioluminescent forest at night with giant mushrooms, glowing plants, mystical atmosphere, small magical creatures, ultra-detailed vegetation, photorealistic textures, fantasy world with realistic lighting"]
243
+ ]
244
+
245
+ gr.Examples(
246
+ examples=examples,
247
+ inputs=prompt_input
248
+ )
249
+
250
+ # Collega il pulsante di generazione
251
+ generate_button.click(
252
+ generate_image_ui,
253
+ inputs=[
254
+ prompt_input,
255
+ model_input,
256
+ steps_input,
257
+ cfg_input,
258
+ height_input,
259
+ width_input,
260
+ negative_prompt_input
261
+ ],
262
+ outputs=[output_image, output_status]
263
+ )
264
+
265
+ return interface
266
 
267
+ # Funzione principale
268
+ def main():
269
+ """Funzione principale"""
270
+ # Crea il generatore
271
+ generator = FluxNineteenGenerator()
272
+
273
+ # Crea l'interfaccia
274
+ interface = create_ui(generator)
275
+
276
+ # Configura l'autenticazione
277
+ username = os.getenv("GRADIO_USERNAME")
278
+ password = os.getenv("GRADIO_PASSWORD")
279
+
280
+ # Verifica se le credenziali sono disponibili
281
+ if username and password:
282
+ auth = (username, password)
283
+ print(f"Autenticazione configurata con username: {username}")
284
+ else:
285
+ # Per test locali, disabilitiamo l'autenticazione
286
+ auth = None
287
+ print("Autenticazione disabilitata per test locali. Su HF Spaces, imposta GRADIO_USERNAME e GRADIO_PASSWORD.")
288
+
289
+ # Avvia l'interfaccia con o senza autenticazione
290
+ interface.launch(auth=auth)
291
 
292
  if __name__ == "__main__":
293
+ main()
requirements.txt CHANGED
@@ -1,6 +1,4 @@
1
- accelerate
2
- diffusers
3
- invisible_watermark
4
- torch
5
- transformers
6
- xformers
 
1
+ gradio>=3.50.2
2
+ requests>=2.31.0
3
+ Pillow>=10.0.0
4
+ python-dotenv>=1.0.0