salomonsky commited on
Commit
2974e4c
1 Parent(s): 5981fd1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -186
app.py CHANGED
@@ -1,204 +1,102 @@
1
- import os
2
- import zipfile
3
- import yaml
4
- import numpy as np
5
- import random
6
  from pathlib import Path
7
  from PIL import Image
8
  import streamlit as st
9
  from huggingface_hub import AsyncInferenceClient
10
- import asyncio
11
  from moviepy.editor import ImageSequenceClip
12
 
13
- try:
14
- with open("config.yaml", "r") as file:
15
- credentials = yaml.safe_load(file)
16
- except Exception as e:
17
- st.error(f"Error al cargar el archivo de configuración: {e}")
18
- credentials = {"username": "", "password": ""}
19
 
20
- MAX_SEED = np.iinfo(np.int32).max
21
- client = AsyncInferenceClient()
22
- DATA_PATH = Path("./data")
23
  DATA_PATH.mkdir(exist_ok=True)
24
- PREDEFINED_SEED = random.randint(0, MAX_SEED)
25
-
26
- async def generate_image(prompt, width, height, seed, model_name):
27
- try:
28
- if seed == -1:
29
- seed = PREDEFINED_SEED
30
- seed = int(seed)
31
- image = await client.text_to_image(
32
- prompt=prompt, height=height, width=width, model=model_name
33
- )
34
- return image, seed
35
- except Exception as e:
36
- return f"Error al generar imagen: {e}", None
37
-
38
- def save_prompt(prompt_text, seed):
39
- try:
40
- prompt_file_path = DATA_PATH / f"prompt_{seed}.txt"
41
- with open(prompt_file_path, "w") as prompt_file:
42
- prompt_file.write(prompt_text)
43
- return prompt_file_path
44
- except Exception as e:
45
- st.error(f"Error al guardar el prompt: {e}")
46
- return None
47
-
48
- async def gen(prompt, width, height, model_name):
49
- combined_prompt = prompt
50
- seed = PREDEFINED_SEED
51
- progress_bar = st.progress(0)
52
- image, seed = await generate_image(combined_prompt, width, height, seed, model_name)
53
  progress_bar.progress(100)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- if isinstance(image, str) and image.startswith("Error"):
56
- progress_bar.empty()
57
- return [image, None]
58
-
59
- image_path = save_image(image, seed)
60
- prompt_file_path = save_prompt(combined_prompt, seed)
61
-
62
- return [str(image_path), str(prompt_file_path)]
63
-
64
- def save_image(image, seed):
65
- try:
66
- image_path = DATA_PATH / f"image_{seed}.jpg"
67
- image.save(image_path, format="JPEG")
68
- return image_path
69
- except Exception as e:
70
- st.error(f"Error al guardar la imagen: {e}")
71
- return None
72
-
73
- def get_storage():
74
- files = [file for file in DATA_PATH.glob("*.jpg") if file.is_file()]
75
- files.sort(key=lambda x: x.stat().st_mtime, reverse=True)
76
- usage = sum([file.stat().st_size for file in files])
77
- return [str(file.resolve()) for file in files], f"Uso total: {usage/(1024.0 ** 3):.3f}GB"
78
-
79
- def get_prompts():
80
- prompt_files = [file for file in DATA_PATH.glob("*.txt") if file.is_file()]
81
- return {file.stem.replace("prompt_", ""): file for file in prompt_files}
82
-
83
- def delete_all_images():
84
- try:
85
- files = [file for file in DATA_PATH.glob("*.jpg")]
86
- prompts = [file for file in DATA_PATH.glob("*.txt")]
87
- for file in files + prompts:
88
- os.remove(file)
89
- st.success("Todas las imágenes y prompts han sido borrados.")
90
- except Exception as e:
91
- st.error(f"Error al borrar archivos: {e}")
92
-
93
- def download_images_as_zip():
94
- zip_path = DATA_PATH / "images.zip"
95
- with zipfile.ZipFile(zip_path, 'w') as zipf:
96
- for file in DATA_PATH.glob("*.jpg"):
97
- zipf.write(file, arcname=file.name)
98
- with open(zip_path, "rb") as zip_file:
99
- st.download_button(label="Descargar imágenes en .zip", data=zip_file, file_name="images.zip", mime="application/zip")
100
-
101
- def create_video_from_images():
102
- try:
103
- image_files = sorted(DATA_PATH.glob("*.jpg"))
104
- if not image_files:
105
- st.error("No hay imágenes disponibles para crear un video.")
106
- return
107
-
108
- image_sequence = [Image.open(image_file) for image_file in image_files]
109
- frame_rate = 2
110
-
111
- clip = ImageSequenceClip([np.array(img) for img in image_sequence], fps=1)
112
- video_path = DATA_PATH / "output_video.mp4"
113
- clip.write_videofile(str(video_path), codec="libx264")
114
-
115
- return video_path
116
-
117
- except Exception as e:
118
- st.error(f"Error al generar el video: {e}")
119
- return None
120
 
121
  def main():
122
  st.set_page_config(layout="wide")
123
- st.title("Generador de Imágenes")
124
 
125
- if "authenticated" not in st.session_state:
126
- st.session_state.authenticated = False
127
 
128
  if not st.session_state.authenticated:
129
- st.subheader("Iniciar sesión")
130
- username = st.text_input("Usuario")
131
- password = st.text_input("Contraseña", type="password")
132
-
133
- if st.button("Ingresar"):
134
- if username == credentials["username"] and password == credentials["password"]:
135
- st.session_state.authenticated = True
136
- st.success("Inicio de sesión exitoso.")
137
- else:
138
- st.error("Usuario o contraseña incorrectos.")
139
  return
140
 
141
- st.warning("Este espacio contiene contenido que no es adecuado para todas las audiencias. Se recomienda discreción.")
142
- agree = st.checkbox("Soy mayor de 18 años y entiendo que el contenido puede no ser apropiado.")
143
-
144
- if agree:
145
- prompt = st.sidebar.text_input("Descripción de la imagen", max_chars=500)
146
- format_option = st.sidebar.selectbox("Formato", ["9:16", "16:9"])
147
- model_option = st.sidebar.selectbox("Modelo", ["enhanceaiteam/Flux-Uncensored-V2", "enhanceaiteam/Flux-uncensored"])
148
-
149
- width, height = (720, 1280) if format_option == "9:16" else (1280, 720)
150
-
151
- if st.sidebar.button("Generar Imagen"):
152
- with st.spinner("Generando imagen..."):
153
- result = asyncio.run(gen(prompt, width, height, model_option))
154
- image_paths = result[0]
155
- prompt_file = result[1]
156
-
157
- if image_paths:
158
- if Path(image_paths).exists():
159
- st.image(image_paths, caption="Imagen Generada")
160
- else:
161
- st.error("El archivo de imagen no existe.")
162
-
163
- if prompt_file and Path(prompt_file).exists():
164
- prompt_text = Path(prompt_file).read_text()
165
- st.write(f"Prompt utilizado: {prompt_text}")
166
- else:
167
- st.write("El archivo del prompt no está disponible.")
168
-
169
- files, usage = get_storage()
170
- st.text(usage)
171
- cols = st.columns(6)
172
- prompts = get_prompts()
173
-
174
- for idx, file in enumerate(files):
175
- with cols[idx % 6]:
176
- image = Image.open(file)
177
- prompt_file = prompts.get(Path(file).stem.replace("image_", ""), None)
178
- prompt_text = Path(prompt_file).read_text() if prompt_file else "No disponible"
179
-
180
- st.image(image, caption=f"Imagen {idx+1}")
181
- st.write(f"Prompt: {prompt_text}")
182
-
183
- if st.button(f"Borrar Imagen {idx+1}", key=f"delete_{idx}"):
184
- try:
185
- os.remove(file)
186
- if prompt_file:
187
- os.remove(prompt_file)
188
- st.success(f"Imagen {idx+1} y su prompt fueron borrados.")
189
- except Exception as e:
190
- st.error(f"Error al borrar la imagen o prompt: {e}")
191
-
192
- if st.sidebar.button("Borrar todas las imágenes"):
193
- delete_all_images()
194
-
195
- if st.sidebar.button("Descargar imágenes en .zip"):
196
- download_images_as_zip()
197
-
198
- if st.button("Generar video con las imágenes"):
199
- video_path = create_video_from_images()
200
- if video_path:
201
- st.video(str(video_path), format="video/mp4")
202
-
203
- if __name__ == "__main__":
204
- main()
 
1
+ import os, zipfile, yaml, numpy as np, random, asyncio
 
 
 
 
2
  from pathlib import Path
3
  from PIL import Image
4
  import streamlit as st
5
  from huggingface_hub import AsyncInferenceClient
 
6
  from moviepy.editor import ImageSequenceClip
7
 
8
+ try: credentials = yaml.safe_load(open("config.yaml"))
9
+ except: st.error("Error al cargar el archivo de configuración."), credentials = {"username": "", "password": ""}
 
 
 
 
10
 
11
+ MAX_SEED, client, DATA_PATH, PREDEFINED_SEED = np.iinfo(np.int32).max, AsyncInferenceClient(), Path("./data"), random.randint(0, MAX_SEED)
 
 
12
  DATA_PATH.mkdir(exist_ok=True)
13
+
14
+ async def generate_image(prompt, width, height, seed, model_name):
15
+ try: return await client.text_to_image(prompt=prompt, height=height, width=width, model=model_name), int(seed)
16
+ except Exception as e: return f"Error al generar imagen: {e}", None
17
+
18
+ def save_prompt(prompt_text, seed):
19
+ try: prompt_file_path = DATA_PATH / f"prompt_{seed}.txt"; open(prompt_file_path, "w").write(prompt_text); return prompt_file_path
20
+ except Exception as e: st.error(f"Error al guardar el prompt: {e}")
21
+
22
+ async def gen(prompt, width, height, model_name):
23
+ seed, progress_bar = PREDEFINED_SEED, st.progress(0)
24
+ image, seed = await generate_image(prompt, width, height, seed, model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  progress_bar.progress(100)
26
+ if isinstance(image, str) and image.startswith("Error"): return [image, None]
27
+ return [str(save_image(image, seed)), str(save_prompt(prompt, seed))]
28
+
29
+ def save_image(image, seed):
30
+ try: image_path = DATA_PATH / f"image_{seed}.jpg"; image.save(image_path, format="JPEG"); return image_path
31
+ except Exception as e: st.error(f"Error al guardar la imagen: {e}")
32
+
33
+ def get_storage():
34
+ files = sorted([file for file in DATA_PATH.glob("*.jpg")], key=lambda x: x.stat().st_mtime, reverse=True)
35
+ return [str(file.resolve()) for file in files], f"Uso total: {sum([file.stat().st_size for file in files])/(1024.0 ** 3):.3f}GB"
36
+
37
+ def get_prompts(): return {file.stem.replace("prompt_", ""): file for file in DATA_PATH.glob("*.txt")}
38
+
39
+ def delete_all_images():
40
+ try: [os.remove(file) for file in DATA_PATH.glob("*.jpg") + DATA_PATH.glob("*.txt")], st.success("Todas las imágenes y prompts han sido borrados.")
41
+ except Exception as e: st.error(f"Error al borrar archivos: {e}")
42
+
43
+ def download_images_as_zip():
44
+ zip_path = DATA_PATH / "images.zip"; zipf = zipfile.ZipFile(zip_path, 'w')
45
+ [zipf.write(file, arcname=file.name) for file in DATA_PATH.glob("*.jpg")]
46
+ with open(zip_path, "rb") as zip_file: st.download_button(label="Descargar imágenes en .zip", data=zip_file, file_name="images.zip", mime="application/zip")
47
 
48
+ def create_video_from_images():
49
+ try: image_files = sorted(DATA_PATH.glob("*.jpg"))
50
+ except: st.error("No hay imágenes disponibles para crear un video."), return
51
+ image_sequence = [Image.open(image_file) for image_file in image_files]
52
+ video_path = DATA_PATH / "output_video.mp4"
53
+ ImageSequenceClip([np.array(img) for img in image_sequence], fps=1).write_videofile(str(video_path), codec="libx264")
54
+ return video_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  def main():
57
  st.set_page_config(layout="wide")
58
+ st.title("Generador de Imágenes Flux")
59
 
60
+ if "authenticated" not in st.session_state: st.session_state.authenticated = False
 
61
 
62
  if not st.session_state.authenticated:
63
+ username, password = st.text_input("Usuario"), st.text_input("Contraseña", type="password")
64
+ if st.button("Ingresar") and username == credentials["username"] and password == credentials["password"]:
65
+ st.session_state.authenticated, st.success("Inicio de sesión exitoso.") = True, True
66
+ elif st.button("Ingresar"): st.error("Usuario o contraseña incorrectos.")
 
 
 
 
 
 
67
  return
68
 
69
+ prompt = st.sidebar.text_input("Descripción de la imagen", max_chars=500)
70
+ format_option = st.sidebar.selectbox("Formato", ["9:16", "16:9"])
71
+ model_option = st.sidebar.selectbox("Modelo", ["enhanceaiteam/Flux-Uncensored-V2", "enhanceaiteam/Flux-uncensored"])
72
+ width, height = (720, 1280) if format_option == "9:16" else (1280, 720)
73
+
74
+ if st.sidebar.button("Generar Imagen"):
75
+ with st.spinner("Generando imagen..."):
76
+ result = asyncio.run(gen(prompt, width, height, model_option))
77
+ image_paths, prompt_file = result[0], result[1]
78
+ if Path(image_paths).exists(): st.image(image_paths, caption="Imagen Generada")
79
+ if prompt_file and Path(prompt_file).exists(): st.write(f"Prompt utilizado: {Path(prompt_file).read_text()}")
80
+
81
+ files, usage = get_storage()
82
+ st.text(usage)
83
+ cols, prompts = st.columns(6), get_prompts()
84
+
85
+ for idx, file in enumerate(files):
86
+ with cols[idx % 6]:
87
+ image = Image.open(file)
88
+ prompt_file = prompts.get(Path(file).stem.replace("image_", ""), None)
89
+ st.image(image, caption=f"Imagen {idx+1}")
90
+ st.write(f"Prompt: {Path(prompt_file).read_text() if prompt_file else 'No disponible'}")
91
+ if st.button(f"Borrar Imagen {idx+1}", key=f"delete_{idx}"):
92
+ os.remove(file)
93
+ if prompt_file: os.remove(prompt_file)
94
+ st.success(f"Imagen {idx+1} y su prompt fueron borrados.")
95
+
96
+ if st.sidebar.button("Borrar todas las imágenes"): delete_all_images()
97
+ if st.sidebar.button("Descargar imágenes en .zip"): download_images_as_zip()
98
+ if st.button("Generar video con las imágenes"):
99
+ video_path = create_video_from_images()
100
+ if video_path: st.video(str(video_path), format="video/mp4")
101
+
102
+ if __name__ == "__main__": main()