Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -20,224 +20,76 @@ clientOpenAI = OpenAI(
|
|
| 20 |
base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
|
| 21 |
)
|
| 22 |
|
| 23 |
-
|
| 24 |
-
"
|
| 25 |
-
"nome": "
|
| 26 |
"stile_immagine": (
|
| 27 |
-
"A
|
| 28 |
-
"
|
| 29 |
-
"
|
| 30 |
-
"A color palette of imperial red, bronze, and muted gold accentuates secretive senatorial silhouettes and subtle sigils. "
|
| 31 |
-
"Designed for a tabletop card game, this style captures clandestine intrigue and political tension with dynamic visual flair."
|
| 32 |
)
|
| 33 |
},
|
| 34 |
-
"
|
| 35 |
-
"nome": "
|
| 36 |
"stile_immagine": (
|
| 37 |
-
"
|
| 38 |
-
"
|
| 39 |
-
"deep red, and aged marble tones. Inspired by medieval European art, "
|
| 40 |
-
"gothic illuminations, and the grandeur of cathedrals. "
|
| 41 |
-
"Designed for a tabletop card game, ensuring clarity, readability, "
|
| 42 |
-
"and a visually immersive experience."
|
| 43 |
)
|
| 44 |
},
|
| 45 |
-
"
|
| 46 |
-
"nome": "
|
| 47 |
"stile_immagine": (
|
| 48 |
-
"A
|
| 49 |
-
"
|
| 50 |
-
"Geometric shapes and patterns evoke the grandeur of pharaohs and pyramids. "
|
| 51 |
-
"Designed for a tabletop card game with clarity and distinct thematic flourishes."
|
| 52 |
)
|
| 53 |
},
|
| 54 |
-
"
|
| 55 |
-
"nome": "
|
| 56 |
"stile_immagine": (
|
| 57 |
-
"
|
| 58 |
-
"and
|
| 59 |
-
"Designed for clarity in a card game with a distinctly ancient Asian aesthetic."
|
| 60 |
)
|
| 61 |
},
|
| 62 |
-
"
|
| 63 |
-
"nome": "
|
| 64 |
"stile_immagine": (
|
| 65 |
-
"
|
| 66 |
-
"
|
| 67 |
-
"in a rich, decorative composition suited for card art."
|
| 68 |
)
|
| 69 |
},
|
| 70 |
-
"
|
| 71 |
-
"nome": "
|
| 72 |
"stile_immagine": (
|
| 73 |
-
"
|
| 74 |
-
"
|
| 75 |
-
"Figures with flowing robes and turbans, capturing courtly splendor."
|
| 76 |
)
|
| 77 |
},
|
| 78 |
-
"Maya": {
|
| 79 |
-
"nome": "Maya",
|
| 80 |
-
"stile_immagine": (
|
| 81 |
-
"Mesoamerican style with stylized glyphs, stepped pyramids, and bright colors. "
|
| 82 |
-
"Incorporate traditional motifs of jaguars and feathers in a decorative, yet readable card layout."
|
| 83 |
-
)
|
| 84 |
-
},
|
| 85 |
-
"Vichinghi": {
|
| 86 |
-
"nome": "Vichinghi",
|
| 87 |
-
"stile_immagine": (
|
| 88 |
-
"Norse-inspired style, with knotwork borders, runic inscriptions, and rugged, "
|
| 89 |
-
"weathered textures. Use earthy colors and references to Viking longships, "
|
| 90 |
-
"mythology, and wooden carvings. Balanced for a legible card game design."
|
| 91 |
-
)
|
| 92 |
-
},
|
| 93 |
-
"Pirati": {
|
| 94 |
-
"nome": "Pirati",
|
| 95 |
-
"stile_immagine": (
|
| 96 |
-
"A dynamic and adventurous style inspired by leggende dei mari e pirati romantici. "
|
| 97 |
-
"Immagini di navi in tempesta, mappe del tesoro, e personaggi con bandane e cappelli tricorni. "
|
| 98 |
-
"Toni marinari, textures consumate dal sale e dall'acqua, e un'atmosfera ribelle ma affascinante, "
|
| 99 |
-
"perfetta per un gioco di carte che evoca il brivido dell'avventura sul mare."
|
| 100 |
-
)
|
| 101 |
-
},
|
| 102 |
-
"Cowboy del Far West": {
|
| 103 |
-
"nome": "Cowboy del Far West",
|
| 104 |
-
"stile_immagine": (
|
| 105 |
-
"Highly detailed, painterly style with a rugged yet cinematic aesthetic. "
|
| 106 |
-
"Rich textures, earthy tones, and a palette dominated by dusty browns, deep reds, and sunset golds. "
|
| 107 |
-
"Inspired by classic Western art, frontier landscapes, and vintage posters. "
|
| 108 |
-
"Iconic elements like cowboy hats, revolvers, and stagecoaches evoke the romance of the Wild West. "
|
| 109 |
-
"Designed for a tabletop card game, ensuring clarity, readability, and an immersive sense of adventure."
|
| 110 |
-
)
|
| 111 |
-
},
|
| 112 |
-
"Steampunk": {
|
| 113 |
-
"nome": "Steampunk",
|
| 114 |
-
"stile_immagine": (
|
| 115 |
-
"Highly detailed, painterly style with a fusion of Victorian elegance and mechanical ingenuity. "
|
| 116 |
-
"Brass gears, intricate machinery, steam-powered contraptions, and industrial backdrops "
|
| 117 |
-
"create a retro-futuristic atmosphere. "
|
| 118 |
-
"A color palette dominated by warm metallics, deep browns, and aged parchment tones. "
|
| 119 |
-
"Inspired by classic steampunk literature and art, ensuring a visually immersive experience "
|
| 120 |
-
"for a tabletop card game with a sense of mystery and innovation."
|
| 121 |
-
)
|
| 122 |
-
},
|
| 123 |
-
"Alieni": {
|
| 124 |
-
"nome": "Alieni",
|
| 125 |
-
"stile_immagine": (
|
| 126 |
-
"Highly detailed, painterly style with a futuristic and surreal aesthetic. "
|
| 127 |
-
"Glowing neon hues, organic and biomechanical forms, and impossible cosmic landscapes "
|
| 128 |
-
"blend to create an otherworldly atmosphere. "
|
| 129 |
-
"A color palette dominated by electric blues, deep purples, and iridescent greens. "
|
| 130 |
-
"Inspired by sci-fi concept art and space opera visuals, ensuring clarity, readability, "
|
| 131 |
-
"and a visually stunning experience for a tabletop card game set in a mysterious universe."
|
| 132 |
-
)
|
| 133 |
-
},
|
| 134 |
-
"Homo Sapiens": {
|
| 135 |
-
"nome": "Homo Sapiens",
|
| 136 |
-
"stile_immagine": (
|
| 137 |
-
"Highly detailed, painterly style with a blend of realism and symbolic representation. "
|
| 138 |
-
"Natural tones, textures inspired by organic matter, and visual elements reflecting "
|
| 139 |
-
"human evolution, history, and cultural development. "
|
| 140 |
-
"A fusion of prehistoric cave paintings, Renaissance anatomical studies, and modern artistic interpretations. "
|
| 141 |
-
"Designed for a tabletop card game, ensuring clarity, readability, and a thought-provoking visual narrative "
|
| 142 |
-
"that bridges the ancient past with the present."
|
| 143 |
-
)
|
| 144 |
-
}
|
| 145 |
}
|
| 146 |
|
| 147 |
-
|
| 148 |
-
# Definizione dello schema Pydantic per un personaggio
|
| 149 |
-
class Character(BaseModel):
|
| 150 |
nome: str
|
| 151 |
-
classe: str
|
| 152 |
-
forza: int
|
| 153 |
-
destrezza: int
|
| 154 |
-
intelligenza: int
|
| 155 |
descrizione: str
|
| 156 |
english_description:str
|
| 157 |
-
storia: str
|
| 158 |
-
|
| 159 |
-
# Definizione dello schema per la risposta contenente una lista di personaggi
|
| 160 |
-
class CharactersResponse(BaseModel):
|
| 161 |
-
personaggi: list[Character]
|
| 162 |
-
|
| 163 |
-
class ActionCard(BaseModel):
|
| 164 |
-
nome_azione: str
|
| 165 |
-
breve_descrizione: str
|
| 166 |
-
breve_descrizione_inglese: str
|
| 167 |
-
|
| 168 |
-
class ActionCardsResponse(BaseModel):
|
| 169 |
-
carte_azione: list[ActionCard]
|
| 170 |
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
descrizione_personaggi = ""
|
| 174 |
-
if carte_azione:
|
| 175 |
-
descrizione_carte_azione = f"Ecco anche le CARTE AZIONE del gioco: {carte_azione.model_dump_json()}"
|
| 176 |
-
if character:
|
| 177 |
-
descrizione_personaggi = f"Ecco i personaggi del gioco di RUOLO a carte. {character.model_dump_json()}"
|
| 178 |
-
response = clientOpenAI.chat.completions.create(
|
| 179 |
-
model='gemini-2.0-flash-thinking-exp-01-21',
|
| 180 |
-
n=1,
|
| 181 |
-
stream=True,
|
| 182 |
-
temperature=creativita,
|
| 183 |
-
messages=[
|
| 184 |
-
{"role": "system", "content": f"Tu sei un creatore di giochi di ruolo a CARTE. Crea un regolamento per un gioco di ruolo sul {nome_ambientazione} sulla base dei personaggi che ti fornirò"},
|
| 185 |
-
{
|
| 186 |
-
"role": "user",
|
| 187 |
-
"content": f"Crea un regolamento!!! {descrizione_personaggi} \n\n {descrizione_carte_azione}"
|
| 188 |
-
}
|
| 189 |
-
]
|
| 190 |
-
)
|
| 191 |
-
story = ""
|
| 192 |
-
st.subheader('Regole 📜')
|
| 193 |
-
placeholder = st.empty()
|
| 194 |
-
for chunk in response:
|
| 195 |
-
if chunk.choices[0].delta.content is not None:
|
| 196 |
-
text_chunk = chunk.choices[0].delta.content
|
| 197 |
-
story += text_chunk
|
| 198 |
-
placeholder.markdown(story)
|
| 199 |
-
print(story)
|
| 200 |
-
return story
|
| 201 |
-
|
| 202 |
-
def generate_ai(num_personaggi, nome_ambientazione, creativita):
|
| 203 |
-
# Costruzione del prompt in italiano per generare i personaggi
|
| 204 |
-
prompt = (
|
| 205 |
-
f"Genera {num_personaggi} personaggi AMBIENTATI NELL'EPOCA {nome_ambientazione}, per un gioco di ruolo a carte."
|
| 206 |
-
"Ogni personaggio deve avere i seguenti campi specificati nel modello ed devono essere COERENTI con l'epoca e l'ambientazione fornita (per esempio, se siamo nel Sacro Romano Impero devono essere nomi italiani) "
|
| 207 |
-
"nel campo STORIA, inventa la una BREVE storia di background del personaggio specificando aneddoti, e altre cose che rendono il personaggio unico. "
|
| 208 |
-
"Restituisci il risultato in formato JSON seguendo lo schema fornito")
|
| 209 |
-
|
| 210 |
-
# Esecuzione della chiamata all'API utilizzando il formato response_format
|
| 211 |
-
completion = clientOpenAI.beta.chat.completions.parse(
|
| 212 |
-
model=MODEL,
|
| 213 |
-
messages=[
|
| 214 |
-
{"role": "system", "content": f"Sei un assistente utile per la generazione di personaggi per un gioco di RUOLO sul {nome_ambientazione}."},
|
| 215 |
-
{"role": "user", "content": prompt},
|
| 216 |
-
],
|
| 217 |
-
temperature=creativita,
|
| 218 |
-
response_format=CharactersResponse,
|
| 219 |
-
)
|
| 220 |
-
characters_response = completion.choices[0].message.parsed
|
| 221 |
-
print(characters_response)
|
| 222 |
-
return characters_response
|
| 223 |
|
| 224 |
-
def
|
| 225 |
prompt = (
|
| 226 |
-
f"Genera {
|
| 227 |
-
"
|
| 228 |
-
|
| 229 |
-
# Esecuzione della chiamata all'API utilizzando il formato response_format
|
| 230 |
completion = clientOpenAI.beta.chat.completions.parse(
|
| 231 |
model=MODEL,
|
| 232 |
messages=[
|
| 233 |
-
{"role": "system", "content": f"Sei un assistente utile per la generazione di
|
| 234 |
{"role": "user", "content": prompt},
|
| 235 |
],
|
| 236 |
temperature=creativita,
|
| 237 |
-
response_format=
|
| 238 |
)
|
| 239 |
-
|
| 240 |
-
|
|
|
|
| 241 |
|
| 242 |
# Funzione per generare le immagini, con gestione errori e retry dopo 10 secondi
|
| 243 |
def generate_image(prompt, max_retries=5):
|
|
@@ -248,8 +100,8 @@ def generate_image(prompt, max_retries=5):
|
|
| 248 |
response = client.images.generate(
|
| 249 |
prompt=prompt,
|
| 250 |
model="black-forest-labs/FLUX.1-schnell-Free",
|
| 251 |
-
width=
|
| 252 |
-
height=
|
| 253 |
steps=4,
|
| 254 |
n=1,
|
| 255 |
response_format="b64_json"
|
|
@@ -262,35 +114,14 @@ def generate_image(prompt, max_retries=5):
|
|
| 262 |
st.error("Numero massimo di tentativi raggiunto. Impossibile generare le immagini.")
|
| 263 |
return None
|
| 264 |
|
| 265 |
-
def generate_images(
|
| 266 |
-
|
| 267 |
-
if character:
|
| 268 |
-
images_bytes_list = []
|
| 269 |
-
if character.nome == "":
|
| 270 |
-
if tipo_carta == "Personaggio":
|
| 271 |
-
prompt = f"{character.english_description} WITH THIS BOLD INSCRIPTION '{nome_carta}'. BORDER COLOR = {colore_bordo}). Use this Style: {stile_immagine}"
|
| 272 |
-
if tipo_carta == "Fronte":
|
| 273 |
-
prompt = f"FRONT OF CARD GAME (WITH THIS BOLD INSCRIPTION IN THE CENTER OF THE CARD = '{nome_carta}'. BORDER COLOR = {colore_bordo}). Use this Syle: {stile_immagine}"
|
| 274 |
-
if tipo_carta == "Retro":
|
| 275 |
-
prompt = ("Design an ornate playing card back with symmetrical filigree"
|
| 276 |
-
"At the center, prominently display the name '" + nome_carta + "' in an elegant, calligraphic style. ")
|
| 277 |
-
prompt += f"BACKGROUND COLOR = {colore_bordo}. Use this Syle: {stile_immagine}"
|
| 278 |
-
else:
|
| 279 |
-
prompt = f"{character.english_description} {stile_immagine}. (INSERT TEXT NAME = {character.nome})"
|
| 280 |
-
st.subheader(f"{character.nome} 🦸♂️")
|
| 281 |
-
st.write(
|
| 282 |
-
f"- **Classe:** {character.classe}\n"
|
| 283 |
-
f"- **Forza:** {character.forza}\n"
|
| 284 |
-
f"- **Destrezza:** {character.destrezza}\n"
|
| 285 |
-
f"- **Intelligenza:** {character.intelligenza}\n"
|
| 286 |
-
f"- **Descrizione:** {character.descrizione}\n",
|
| 287 |
-
f"- **Storia:** {character.storia}"
|
| 288 |
-
)
|
| 289 |
-
if carta_azione:
|
| 290 |
-
prompt = f"PLAYING CARD FOR A CARD GAME WITHOUT CHARACTER WITH THIS BOLD INSCRIPTION IN THE CENTER OF THE CARD: '{carta_azione.nome_azione}'. USE THIS STYLE: {stile_immagine}.)"
|
| 291 |
images_bytes_list = []
|
| 292 |
-
|
| 293 |
-
|
|
|
|
|
|
|
|
|
|
| 294 |
print(prompt)
|
| 295 |
for numero in range(num_immagini):
|
| 296 |
images_data = generate_image(prompt)
|
|
@@ -311,66 +142,38 @@ def generate_images(character: Character, carta_azione: ActionCard, stile_immagi
|
|
| 311 |
return images_bytes_list
|
| 312 |
|
| 313 |
def main():
|
| 314 |
-
st.title("
|
| 315 |
st.sidebar.header("Impostazioni")
|
| 316 |
-
|
| 317 |
-
stile_default =
|
| 318 |
-
|
| 319 |
stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
|
| 320 |
-
|
| 321 |
-
auto =
|
|
|
|
|
|
|
| 322 |
prompt_input = ""
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
nome_carta = st.sidebar.text_input("Nome Carta", value="Carmine")
|
| 328 |
-
colore_bordo = st.sidebar.selectbox("Colore Bordo",("Blue", "Red", "Yellow", "Green", "Pink", "Black", "White"))
|
| 329 |
-
else:
|
| 330 |
-
num_personaggi = st.sidebar.slider("Personaggi", min_value=0, max_value=30, value=5, disabled=not auto)
|
| 331 |
-
num_carte_azione = st.sidebar.slider("Carte Azione", min_value=0, max_value=10, value=0, disabled=not auto)
|
| 332 |
-
genera_regolamento = st.sidebar.toggle(label= 'Regolamento', value = True, disabled=not auto)
|
| 333 |
-
tipo_carta = None
|
| 334 |
-
nome_carta = None
|
| 335 |
-
colore_bordo = None
|
| 336 |
-
|
| 337 |
-
num_immagini = st.sidebar.slider("Variazioni Immagini", min_value=1, max_value=6, value=2)
|
| 338 |
-
creativita = st.sidebar.slider("Creativita", min_value=0.1, max_value=1.0, value=0.8, step=0.1)
|
| 339 |
submit_button = st.sidebar.button(label="Genera Immagine", type="primary", use_container_width=True)
|
| 340 |
-
st.write("
|
| 341 |
|
| 342 |
if submit_button:
|
| 343 |
-
carte_azione = None
|
| 344 |
-
characters = None
|
| 345 |
if auto:
|
| 346 |
-
if
|
| 347 |
-
with st.spinner('Generazione
|
| 348 |
-
|
| 349 |
-
st.subheader('
|
| 350 |
-
df = pd.DataFrame([{k: v for k, v in
|
| 351 |
-
st.dataframe(df, hide_index=True, use_container_width=True)
|
| 352 |
-
st.divider()
|
| 353 |
-
if num_carte_azione > 0:
|
| 354 |
-
with st.spinner('Generazione Carte Azione'):
|
| 355 |
-
carte_azione = generate_card_ai(num_carte_azione, nome_ambientazione, creativita)
|
| 356 |
-
st.subheader('Carte Azione 📒')
|
| 357 |
-
df = pd.DataFrame([{k: v for k, v in carta_azione.model_dump().items() if k != "breve_descrizione_inglese"} for carta_azione in carte_azione.carte_azione])
|
| 358 |
st.dataframe(df, hide_index=True, use_container_width=True)
|
| 359 |
st.divider()
|
| 360 |
-
if genera_regolamento:
|
| 361 |
-
with st.spinner('Generazione Regolamento'):
|
| 362 |
-
generate_story(characters, carte_azione, nome_ambientazione, creativita)
|
| 363 |
-
st.divider()
|
| 364 |
-
else:
|
| 365 |
-
characters = CharactersResponse(personaggi=[Character(nome="", classe="Guerriero", forza=10, destrezza=8, intelligenza=6, storia="", descrizione="Un forte guerriero", english_description=prompt_input)])
|
| 366 |
with st.spinner('Generazione Immagini'):
|
| 367 |
images = []
|
| 368 |
-
if
|
| 369 |
-
for
|
| 370 |
-
images.extend(generate_images(
|
| 371 |
-
if carte_azione:
|
| 372 |
-
for carta_azione in carte_azione.carte_azione:
|
| 373 |
-
images.extend(generate_images(None, carta_azione, stile_immagine, num_immagini))
|
| 374 |
if images:
|
| 375 |
zip_buffer = io.BytesIO()
|
| 376 |
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
|
|
@@ -387,5 +190,5 @@ def main():
|
|
| 387 |
st.success("Immagini generate con successo!")
|
| 388 |
|
| 389 |
if __name__ == "__main__":
|
| 390 |
-
st.set_page_config(page_title="
|
| 391 |
-
main()
|
|
|
|
| 20 |
base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
|
| 21 |
)
|
| 22 |
|
| 23 |
+
LOGO_STYLES = {
|
| 24 |
+
"Minimalist": {
|
| 25 |
+
"nome": "Minimalist",
|
| 26 |
"stile_immagine": (
|
| 27 |
+
"A minimalist logo design prompt focusing on simplicity and essential elements. "
|
| 28 |
+
"Clean lines, a limited color palette, and strategic use of negative space. "
|
| 29 |
+
"Ideal for conveying modernity and clarity."
|
|
|
|
|
|
|
| 30 |
)
|
| 31 |
},
|
| 32 |
+
"Modern": {
|
| 33 |
+
"nome": "Modern",
|
| 34 |
"stile_immagine": (
|
| 35 |
+
"A modern logo design prompt featuring abstract forms, innovative color combinations, "
|
| 36 |
+
"and dynamic geometric shapes. Sleek typography and a contemporary aesthetic make it perfect for tech companies and startups."
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
)
|
| 38 |
},
|
| 39 |
+
"Retro": {
|
| 40 |
+
"nome": "Retro",
|
| 41 |
"stile_immagine": (
|
| 42 |
+
"A retro logo design prompt evoking nostalgia with vintage color schemes, classic typography, "
|
| 43 |
+
"and design elements reminiscent of the past. Perfect for brands that want to express heritage and authenticity."
|
|
|
|
|
|
|
| 44 |
)
|
| 45 |
},
|
| 46 |
+
"Vintage": {
|
| 47 |
+
"nome": "Vintage",
|
| 48 |
"stile_immagine": (
|
| 49 |
+
"A vintage logo design prompt inspired by bygone eras. Emphasizes handcrafted details, worn textures, "
|
| 50 |
+
"and a nostalgic atmosphere, ideal for artisanal products or brands with a long-standing tradition."
|
|
|
|
| 51 |
)
|
| 52 |
},
|
| 53 |
+
"Geometric": {
|
| 54 |
+
"nome": "Geometric",
|
| 55 |
"stile_immagine": (
|
| 56 |
+
"A geometric logo design prompt that leverages simple, precise shapes, clean lines, and symmetry. "
|
| 57 |
+
"Communicates order, professionalism, and a rational approach to design."
|
|
|
|
| 58 |
)
|
| 59 |
},
|
| 60 |
+
"Typographic": {
|
| 61 |
+
"nome": "Typographic",
|
| 62 |
"stile_immagine": (
|
| 63 |
+
"A typographic logo design prompt focused on the creative use of lettering. "
|
| 64 |
+
"Bold typography paired with minimal color usage highlights the strength of word-based identities."
|
|
|
|
| 65 |
)
|
| 66 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
}
|
| 68 |
|
| 69 |
+
class Logo(BaseModel):
|
|
|
|
|
|
|
| 70 |
nome: str
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
descrizione: str
|
| 72 |
english_description:str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
+
class Loghi(BaseModel):
|
| 75 |
+
loghi: list[Logo]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
+
def generate_ai(num_loghi, tema, creativita):
|
| 78 |
prompt = (
|
| 79 |
+
f"Genera {num_loghi} prompt per la generazione immagini che trasmetta questo: {tema}"
|
| 80 |
+
"Sii molto SINTETICO e usa SIMBOLI stilizzati e non troppi oggetti. Restituisci il risultato in formato JSON seguendo lo schema fornito")
|
|
|
|
|
|
|
| 81 |
completion = clientOpenAI.beta.chat.completions.parse(
|
| 82 |
model=MODEL,
|
| 83 |
messages=[
|
| 84 |
+
{"role": "system", "content": f"Sei un assistente utile per la generazione di IDEE per la generazioni immagini su questo tema: {tema}."},
|
| 85 |
{"role": "user", "content": prompt},
|
| 86 |
],
|
| 87 |
temperature=creativita,
|
| 88 |
+
response_format=Loghi,
|
| 89 |
)
|
| 90 |
+
loghi = completion.choices[0].message.parsed
|
| 91 |
+
print(loghi)
|
| 92 |
+
return loghi
|
| 93 |
|
| 94 |
# Funzione per generare le immagini, con gestione errori e retry dopo 10 secondi
|
| 95 |
def generate_image(prompt, max_retries=5):
|
|
|
|
| 100 |
response = client.images.generate(
|
| 101 |
prompt=prompt,
|
| 102 |
model="black-forest-labs/FLUX.1-schnell-Free",
|
| 103 |
+
width=1024,
|
| 104 |
+
height=1024,
|
| 105 |
steps=4,
|
| 106 |
n=1,
|
| 107 |
response_format="b64_json"
|
|
|
|
| 114 |
st.error("Numero massimo di tentativi raggiunto. Impossibile generare le immagini.")
|
| 115 |
return None
|
| 116 |
|
| 117 |
+
def generate_images(logo: Logo, nome_stile, stile_immagine, num_immagini, colori: list[str] = None):
|
| 118 |
+
if logo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
images_bytes_list = []
|
| 120 |
+
colors_str = " ".join(colori) if colori else ""
|
| 121 |
+
|
| 122 |
+
prompt = f"Create a Simple Logo in {nome_stile} STYLE background white, and COLORS '{colors_str}' of '{logo.english_description}'. use this style {stile_immagine}"
|
| 123 |
+
st.subheader(f"{logo.nome} 🖌️")
|
| 124 |
+
st.write(logo.descrizione)
|
| 125 |
print(prompt)
|
| 126 |
for numero in range(num_immagini):
|
| 127 |
images_data = generate_image(prompt)
|
|
|
|
| 142 |
return images_bytes_list
|
| 143 |
|
| 144 |
def main():
|
| 145 |
+
st.title("Logo Generator AI 🎨")
|
| 146 |
st.sidebar.header("Impostazioni")
|
| 147 |
+
selected_stile = st.sidebar.selectbox("Ambientazione", list(LOGO_STYLES.keys()), index=0)
|
| 148 |
+
stile_default = LOGO_STYLES[selected_stile]["stile_immagine"]
|
| 149 |
+
nome_stile = LOGO_STYLES[selected_stile]["nome"]
|
| 150 |
stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
|
| 151 |
+
|
| 152 |
+
auto = True
|
| 153 |
+
tema = st.sidebar.text_input("Tema Logo", value="Formazione Aziendale")
|
| 154 |
+
#auto = st.sidebar.toggle(label= 'Generazione automatica', value = True)
|
| 155 |
prompt_input = ""
|
| 156 |
+
colori = st.sidebar.multiselect("Colori", ["Blue", "Orange", "Green", "Yellow", "Red", "Purple"], ["Blue", "Orange"])
|
| 157 |
+
num_loghi = st.sidebar.slider("Loghi", min_value=0, max_value=30, value=10, disabled=not auto)
|
| 158 |
+
num_immagini = st.sidebar.slider("Variazioni", min_value=1, max_value=6, value=2)
|
| 159 |
+
creativita = st.sidebar.slider("Creativita", min_value=0.1, max_value=1.0, value=0.95, step=0.1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
submit_button = st.sidebar.button(label="Genera Immagine", type="primary", use_container_width=True)
|
| 161 |
+
st.write("Genera il tuo **Logo Aziendale** tramite l'AI")
|
| 162 |
|
| 163 |
if submit_button:
|
|
|
|
|
|
|
| 164 |
if auto:
|
| 165 |
+
if num_loghi > 0:
|
| 166 |
+
with st.spinner('Generazione Loghi'):
|
| 167 |
+
loghi = generate_ai(num_loghi, tema, creativita)
|
| 168 |
+
st.subheader('Loghi 💡')
|
| 169 |
+
df = pd.DataFrame([{k: v for k, v in logo.model_dump().items() if k != ""} for logo in loghi.loghi])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
st.dataframe(df, hide_index=True, use_container_width=True)
|
| 171 |
st.divider()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
with st.spinner('Generazione Immagini'):
|
| 173 |
images = []
|
| 174 |
+
if loghi:
|
| 175 |
+
for logo in loghi.loghi:
|
| 176 |
+
images.extend(generate_images(logo, nome_stile, stile_immagine, num_immagini, colori))
|
|
|
|
|
|
|
|
|
|
| 177 |
if images:
|
| 178 |
zip_buffer = io.BytesIO()
|
| 179 |
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
|
|
|
|
| 190 |
st.success("Immagini generate con successo!")
|
| 191 |
|
| 192 |
if __name__ == "__main__":
|
| 193 |
+
st.set_page_config(page_title="Logo Generator AI", page_icon="🎨", layout="wide")
|
| 194 |
+
main()
|