salomonsky commited on
Commit
0ad1714
verified
1 Parent(s): 5ce6479

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -188
app.py CHANGED
@@ -1,204 +1,186 @@
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
-
124
- if "authenticated" not in st.session_state:
125
- st.session_state.authenticated = False
126
-
127
- if not st.session_state.authenticated:
128
- st.subheader("Iniciar sesi贸n")
129
- username = st.text_input("Usuario", value="admin")
130
- password = st.text_input("Contrase帽a", value="flux3x", type="password")
131
-
132
- if st.button("Ingresar"):
133
- if username == credentials["username"] and password == credentials["password"]:
134
- st.session_state.authenticated = True
135
- st.success("Inicio de sesi贸n exitoso.")
136
- else:
137
- st.error("Usuario o contrase帽a incorrectos.")
138
  return
139
-
140
- st.warning("Este espacio contiene contenido que no es adecuado para todas las audiencias. Se recomienda discreci贸n.")
141
- agree = st.checkbox("Soy mayor de 18 a帽os y entiendo que el contenido puede no ser apropiado.")
142
- st.title("Flux +Uncensored")
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
  from pathlib import Path
2
  from PIL import Image
3
  import streamlit as st
4
+ import insightface
5
+ from insightface.app import FaceAnalysis
6
+ from huggingface_hub import InferenceClient
7
+ import os
8
+ import random
9
+ import numpy as np
10
+ import yaml
11
 
12
+ with open("config.yaml", "r") as file:
13
+ credentials = yaml.safe_load(file)
 
 
 
 
14
 
15
  MAX_SEED = np.iinfo(np.int32).max
16
+ client = InferenceClient()
17
  DATA_PATH = Path("./data")
18
  DATA_PATH.mkdir(exist_ok=True)
19
  PREDEFINED_SEED = random.randint(0, MAX_SEED)
20
+ HF_TOKEN_UPSCALER = os.environ.get("HF_TOKEN")
21
+
22
+ def get_upscale_finegrain(prompt, img_path, upscale_factor):
23
+ upscale_client = InferenceClient("fal/AuraSR-v2", hf_token=HF_TOKEN_UPSCALER)
24
+ result = upscale_client.predict(input_image=handle_file(img_path), prompt=prompt, upscale_factor=upscale_factor)
25
+ return result[1] if isinstance(result, list) and len(result) > 1 else None
26
+
27
+ def authenticate_user(username, password):
28
+ return username == credentials["username"] and password == credentials["password"]
29
+
30
+ def list_saved_images():
31
+ image_files = sorted(DATA_PATH.glob("*.jpg"))
32
+ return image_files
33
+
34
+ def prepare_face_app():
35
+ app = FaceAnalysis(name='buffalo_l')
36
+ app.prepare(ctx_id=0, det_size=(640, 640))
37
+ swapper = insightface.model_zoo.get_model('onix.onnx')
38
+ return app, swapper
39
+
40
+ app, swapper = prepare_face_app()
41
+
42
+ def sort_faces(faces):
43
+ return sorted(faces, key=lambda x: x.bbox[0])
44
+
45
+ def get_face(faces, face_id):
46
+ return faces[face_id - 1]
47
+
48
+ def swap_faces(source_image, source_face_index, destination_image, destination_face_index):
49
+ faces = sort_faces(app.get(source_image))
50
+ source_face = get_face(faces, source_face_index)
51
+ res_faces = sort_faces(app.get(destination_image))
52
+ res_face = get_face(res_faces, destination_face_index)
53
+ result = swapper.get(destination_image, res_face, source_face, paste_back=True)
54
+ return result
55
+
56
+ def generate_image(prompt, width, height, seed, model_name):
57
+ if seed == -1:
58
+ seed = random.randint(0, MAX_SEED)
59
+ image = client.text_to_image(prompt=prompt, height=height, width=width, model=model_name)
60
+ return image, seed
61
+
62
+ def display_gallery():
63
+ st.header("Galer铆a de Im谩genes Guardadas")
64
+ images = list_saved_images()
65
+ if images:
66
+ cols = st.columns(8)
67
+ for i, image_file in enumerate(images):
68
+ with cols[i % 8]:
69
+ st.image(str(image_file), caption=image_file.name, use_column_width=True)
70
+ prompt = get_prompt_for_image(image_file.name)
71
+ st.write(prompt[:100])
72
+ if st.button(f"FaceSwap", key=f"select_{i}_{image_file.name}"):
73
+ st.session_state['generated_image_path'] = str(image_file)
74
+ st.success("Imagen seleccionada")
75
+ if st.button(f"Borrar", key=f"delete_{i}_{image_file.name}"):
76
+ if image_file.exists():
77
+ os.remove(image_file)
78
+ st.success("Imagen borrada")
79
+ else:
80
+ st.warning("La imagen no existe.")
81
+ else:
82
+ st.info("No hay im谩genes guardadas.")
83
+
84
+ def save_prompt(prompt):
85
+ with open(DATA_PATH / "prompts.txt", "a") as f:
86
+ f.write(prompt + "\n")
87
+ st.success("Prompt guardado.")
88
+
89
+ def generate_variations(prompt, num_variants, use_enhanced):
90
+ instructions = [
91
+ "With this words, create a photorealistic description for a detailed txt2img prompt in English in 200 characters maximum",
92
+ "With this idea, write a creative, realistic, and detailed text-to-image prompt in English in 200 characters maximum",
93
+ "With this text, generate a descriptive and True to life txt2img prompt in English in 200 characters maximum",
94
+ "With my idea, describe a photorealistic scene with detailed illumination for a txt2img prompt in English in 200 characters maximum",
95
+ "With this concept, give a realistic, elegant txt2img prompt in English, emphasizing photorealism in 200 characters maximum",
96
+ "With this perspective, conform a visually dynamic and hyperrealistic txt2img prompt in English in 200 characters maximum",
97
+ "With this inspiration, realize a cinematic txt2img prompt in English with hyperrealistic elements in 200 characters maximum",
98
+ "With my idea, make a lifelike and txt2img prompt in English, focusing on photorealistic depth in 200 characters maximum"
99
+ ]
100
+ prompts = set()
101
+ while len(prompts) < num_variants:
102
+ instruction = random.choice(instructions)
103
+ enhanced_prompt = f"{instruction}: {prompt}"
104
+ prompts.add(enhanced_prompt)
105
+ return list(prompts)
106
+
107
+ def gen(prompts, width, height, model_name, num_variants=1):
108
+ images = []
109
+ seeds = random.sample(range(MAX_SEED), num_variants)
110
+ for idx, (prompt, seed) in enumerate(zip(prompts[:num_variants], seeds)):
111
+ image, _ = generate_image(prompt, width, height, seed, model_name)
112
+ image_path = save_image(image, f"generated_image_{seed}.jpg")
113
+ if image_path:
114
+ save_prompt(f"generated_image_{seed}.jpg: {prompt}")
115
+ st.success(f"Imagen {idx + 1} generada")
116
+ images.append(str(image_path))
117
+ return images
118
+
119
+ def get_prompt_for_image(image_name):
120
+ prompts = {}
121
  try:
122
+ with open(DATA_PATH / "prompts.txt", "r") as f:
123
+ for line in f:
124
+ if line.startswith(image_name):
125
+ prompts[image_name] = line.split(": ", 1)[1].strip()
126
+ except FileNotFoundError:
127
+ return "No hay prompt asociado."
128
+ return prompts.get(image_name, "No hay prompt asociado.")
129
+
130
+ def login_form():
131
+ st.title("Iniciar Sesi贸n")
132
+ username = st.text_input("Usuario", value="admin")
133
+ password = st.text_input("Contrase帽a", value="flux3x", type="password")
134
+ if st.button("Iniciar Sesi贸n"):
135
+ if authenticate_user(username, password):
136
+ st.success("Autenticaci贸n exitosa.")
137
+ st.session_state['authenticated'] = True
138
+ else:
139
+ st.error("Credenciales incorrectas. Intenta de nuevo.")
140
+
141
+ def save_image(image, filename):
142
+ image_path = DATA_PATH / filename
143
+ if isinstance(image, bytes):
144
+ with open(image_path, "wb") as f:
145
+ f.write(image)
146
+ else:
147
+ image.save(image_path)
148
+ return image_path
149
+
150
+ def upload_image_to_gallery():
151
+ uploaded_image = st.sidebar.file_uploader("Sube una imagen a la galer铆a", type=["jpg", "jpeg", "png"])
152
+ if uploaded_image:
153
+ image = Image.open(uploaded_image)
154
+ image_path = save_image(image, f"{uploaded_image.name}")
155
+ if image_path:
156
+ save_prompt(f"{uploaded_image.name}: uploaded by user")
157
+ st.sidebar.success(f"Imagen subida: {image_path}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  def main():
160
  st.set_page_config(layout="wide")
161
+ if 'authenticated' not in st.session_state or not st.session_state['authenticated']:
162
+ login_form()
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  return
164
+ st.title("Flux +Upscale +Prompt Enhancer +FaceSwap")
165
+ generated_image_path = st.session_state.get('generated_image_path')
166
+ prompt = st.sidebar.text_area("Descripci贸n de la imagen", height=150, max_chars=500)
167
+ format_option = st.sidebar.selectbox("Formato", ["9:16", "16:9", "1:1"])
168
+ model_option = st.sidebar.selectbox("Modelo", ["black-forest-labs/FLUX.1-schnell", "black-forest-labs/FLUX.1-dev"])
169
+ upscale_checkbox = st.sidebar.checkbox("Escalar imagen")
170
+ prompt_enhance = st.sidebar.checkbox("Mejorar Prompt", True)
171
+ num_variants = st.sidebar.slider("N煤mero de im谩genes", 1, 8, 8)
172
+ width, height = (720, 1280) if format_option == "9:16" else (1280, 720) if format_option == "16:9" else (1280, 1280)
173
+ if prompt:
174
+ prompts = generate_variations(prompt, num_variants=num_variants, use_enhanced=prompt_enhance)
175
+ if st.sidebar.button("Generar Im谩genes"):
176
+ images = gen(prompts, width, height, model_option, num_variants)
177
+ if generated_image_path and upscale_checkbox:
178
+ upscale_factor = st.sidebar.slider("Factor de Escalado", 1, 4, 2)
179
+ improved_image = get_upscale_finegrain(prompt, generated_image_path, upscale_factor)
180
+ if improved_image:
181
+ st.image(improved_image, caption="Imagen Escalada", use_column_width=True)
182
+ upload_image_to_gallery()
183
+ display_gallery()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  if __name__ == "__main__":
186
+ main()