salomonsky commited on
Commit
d7bca1e
verified
1 Parent(s): 9a9d310

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -107
app.py CHANGED
@@ -8,55 +8,76 @@ import os
8
  import random
9
  import numpy as np
10
  import yaml
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  try:
13
  with open("config.yaml", "r") as file:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  credentials = yaml.safe_load(file)
15
  except Exception as e:
16
- st.error(f"Error al cargar el archivo de configuraci贸n: {e}")
17
  credentials = {"username": "", "password": ""}
18
 
19
- MAX_SEED = np.iinfo(np.int32).max
20
  client = InferenceClient()
21
  DATA_PATH = Path("./data")
22
  DATA_PATH.mkdir(exist_ok=True)
23
- PREDEFINED_SEED = random.randint(0, MAX_SEED)
24
  HF_TOKEN_UPSCALER = os.environ.get("HF_TOKEN")
25
 
26
- if not HF_TOKEN_UPSCALER:
27
- st.warning("HF_TOKEN no est谩 configurado. Algunas funcionalidades pueden no funcionar.")
 
 
 
 
28
 
29
  def get_upscale_finegrain(prompt, img_path, upscale_factor):
30
  try:
31
  upscale_client = InferenceClient("fal/AuraSR-v2", hf_token=HF_TOKEN_UPSCALER)
32
- result = upscale_client.predict(input_image=handle_file(img_path), prompt=prompt, upscale_factor=upscale_factor)
33
  return result[1] if isinstance(result, list) and len(result) > 1 else None
34
  except Exception as e:
35
  st.error(f"Error al mejorar la imagen: {e}")
36
  return None
37
 
 
 
 
 
 
 
38
  def authenticate_user(username, password):
39
  return username == credentials["username"] and password == credentials["password"]
40
 
41
  def list_saved_images():
42
- try:
43
- image_files = sorted(
44
- DATA_PATH.glob("*.jpg"),
45
- key=lambda x: x.stat().st_mtime,
46
- reverse=True
47
- )
48
- return image_files
49
- except Exception as e:
50
- st.error(f"Error al listar im谩genes guardadas: {e}")
51
- return []
52
-
53
- def prepare_face_app():
54
- app = FaceAnalysis(name='buffalo_l')
55
- app.prepare(ctx_id=0, det_size=(640, 640))
56
- swapper = insightface.model_zoo.get_model('onix.onnx')
57
- return app, swapper
58
-
59
- app, swapper = prepare_face_app()
60
 
61
  def sort_faces(faces):
62
  return sorted(faces, key=lambda x: x.bbox[0])
@@ -78,19 +99,18 @@ def swap_faces(source_image, source_face_index, destination_image, destination_f
78
 
79
  def generate_image(prompt, width, height, seed, model_name):
80
  try:
81
- seed = int(seed) if seed != -1 else random.randint(0, MAX_SEED)
82
- image = client.text_to_image(
83
- prompt=prompt,
84
- height=height,
85
- width=width,
86
- model=model_name,
87
- seed=seed
88
- )
89
- return image, seed
 
90
  except Exception as e:
91
  st.error(f"Error al generar imagen: {e}")
92
- if hasattr(e, 'response') and e.response is not None:
93
- st.error(f"Detalles del error: {e.response.text}")
94
  return None, seed
95
 
96
  def display_gallery():
@@ -111,119 +131,104 @@ def display_gallery():
111
  os.remove(image_file)
112
  st.success("Imagen borrada")
113
  display_gallery()
114
- else:
115
- st.warning("La imagen no existe.")
116
- else:
117
- st.info("No hay im谩genes guardadas.")
118
 
119
- def save_prompt(prompt):
120
  with open(DATA_PATH / "prompts.txt", "a") as f:
121
- f.write(prompt + "\n")
122
- st.success("Prompt guardado.")
 
 
 
 
 
 
 
 
 
 
123
 
124
- def generate_variations(prompt, num_variants, use_enhanced):
 
 
 
 
 
 
 
 
 
 
 
125
  if use_enhanced:
126
- instructions = [
127
- "With this words, create a photorealistic description for a detailed txt2img prompt in English in 200 characters maximum",
128
- "With this idea, write a creative, realistic, and detailed text-to-image prompt in English in 200 characters maximum",
129
- "With this text, generate a descriptive and True to life txt2img prompt in English in 200 characters maximum",
130
- "With my idea, describe a photorealistic scene with detailed illumination for a txt2img prompt in English in 200 characters maximum",
131
- "With this concept, give a realistic, elegant txt2img prompt in English, emphasizing photorealism in 200 characters maximum",
132
- "With this perspective, conform a visually dynamic and hyperrealistic txt2img prompt in English in 200 characters maximum",
133
- "With this inspiration, realize a cinematic txt2img prompt in English with hyperrealistic elements in 200 characters maximum",
134
- "With my idea, make a lifelike and txt2img prompt in English, focusing on photorealistic depth in 200 characters maximum"
135
- ]
136
- prompts = set()
137
- while len(prompts) < num_variants:
138
- instruction = random.choice(instructions)
139
- enhanced_prompt = f"{instruction}: {prompt}"
140
- prompts.add(enhanced_prompt)
141
- return list(prompts)
142
  else:
143
- return [prompt] * num_variants
 
144
 
145
- def gen(prompts, width, height, model_name, num_variants=1):
146
  images = []
147
  seeds = []
148
 
149
  while len(seeds) < num_variants:
150
- new_seed = random.randint(0, MAX_SEED)
151
- if new_seed not in seeds:
152
- seeds.append(new_seed)
153
 
154
- try:
155
- prompts_to_use = prompts[:num_variants]
156
- if len(prompts_to_use) < num_variants:
157
- prompts_to_use.extend([prompts_to_use[-1]] * (num_variants - len(prompts_to_use)))
158
-
159
- for idx, (seed, prompt) in enumerate(zip(seeds, prompts_to_use)):
160
- image, used_seed = generate_image(prompt, width, height, seed, model_name)
161
  if image:
162
- image_path = save_image(image, f"generated_image_{seed}.jpg")
163
- if image_path:
164
- clean_prompt = prompt.split(": ")[-1] if ": " in prompt else prompt
165
- save_prompt(f"generated_image_{seed}.jpg: {clean_prompt}")
166
- st.success(f"Imagen {idx + 1} generada")
167
- images.append(str(image_path))
168
- except Exception as e:
169
- st.error(f"Error al generar im谩genes: {e}")
170
 
171
  return images
172
 
173
  def get_prompt_for_image(image_name):
174
- prompts = {}
175
  try:
176
  with open(DATA_PATH / "prompts.txt", "r") as f:
177
  for line in f:
178
  if line.startswith(image_name):
179
- full_prompt = line.split(": ", 1)[1].strip()
180
- if ":" in full_prompt:
181
- prompt = full_prompt.split(": ")[-1].strip()
182
- else:
183
- prompt = full_prompt
184
- prompts[image_name] = prompt
185
  except FileNotFoundError:
186
- return "No hay prompt asociado."
187
- return prompts.get(image_name, "No hay prompt asociado.")
188
 
189
  def login_form():
190
  st.title("Iniciar Sesi贸n")
191
  username = st.text_input("Usuario", value="admin")
192
- password = st.text_input("Contrase帽a", value="flux3", type="password")
193
  if st.button("Iniciar Sesi贸n"):
194
  if authenticate_user(username, password):
195
- st.success("Autenticaci贸n exitosa.")
196
  st.session_state['authenticated'] = True
 
197
  else:
198
  st.error("Credenciales incorrectas. Intenta de nuevo.")
199
 
200
- def save_image(image, filename):
201
- try:
202
- image_path = DATA_PATH / filename
203
- if isinstance(image, bytes):
204
- with open(image_path, "wb") as f:
205
- f.write(image)
206
- else:
207
- image.save(image_path)
208
- return image_path
209
- except Exception as e:
210
- st.error(f"Error al guardar la imagen: {e}")
211
- return None
212
-
213
  def upload_image_to_gallery():
214
  uploaded_image = st.sidebar.file_uploader("Sube una imagen a la galer铆a", type=["jpg", "jpeg", "png"])
215
  if uploaded_image:
216
  image = Image.open(uploaded_image)
217
- image_path = save_image(image, f"{uploaded_image.name}")
218
- if image_path:
219
- save_prompt(f"{uploaded_image.name}: uploaded by user")
220
- st.sidebar.success(f"Imagen subida: {image_path}")
 
 
221
 
222
  def main():
223
  st.set_page_config(layout="wide")
224
  if 'authenticated' not in st.session_state or not st.session_state['authenticated']:
225
  login_form()
226
  return
 
227
  st.title("Flux +Upscale +Prompt Enhancer +FaceSwap")
228
  generated_image_path = st.session_state.get('generated_image_path')
229
  prompt = st.sidebar.text_area("Descripci贸n de la imagen", height=150, max_chars=500)
 
8
  import random
9
  import numpy as np
10
  import yaml
11
+ import time
12
+ import logging
13
+ from typing import Tuple, Optional, List, Dict
14
+ from dataclasses import dataclass
15
+
16
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
17
+ logger = logging.getLogger(__name__)
18
+
19
+ @dataclass
20
+ class AppConfig:
21
+ MAX_SEED: int = np.iinfo(np.int32).max
22
+ DEFAULT_WIDTH: int = 1280
23
+ DEFAULT_HEIGHT: int = 720
24
+ SUPPORTED_FORMATS: List[str] = ["9:16", "16:9", "1:1"]
25
+ CLEANUP_DAYS: int = 7
26
+ MAX_GALLERY_SIZE: int = 1000
27
 
28
  try:
29
  with open("config.yaml", "r") as file:
30
+ config = yaml.safe_load(file)
31
+ except Exception as e:
32
+ logger.error(f"Error al cargar el archivo de configuraci贸n: {e}")
33
+ config = {
34
+ "development": {
35
+ "max_image_size": 1280,
36
+ "supported_formats": ["9:16", "16:9", "1:1"],
37
+ "models": ["black-forest-labs/FLUX.1-schnell", "black-forest-labs/FLUX.1-dev"],
38
+ "storage": {"cleanup_after_days": 7, "max_gallery_size": 1000}
39
+ }
40
+ }
41
+
42
+ try:
43
+ with open("credentials.yaml", "r") as file:
44
  credentials = yaml.safe_load(file)
45
  except Exception as e:
 
46
  credentials = {"username": "", "password": ""}
47
 
48
+ MAX_SEED = AppConfig.MAX_SEED
49
  client = InferenceClient()
50
  DATA_PATH = Path("./data")
51
  DATA_PATH.mkdir(exist_ok=True)
 
52
  HF_TOKEN_UPSCALER = os.environ.get("HF_TOKEN")
53
 
54
+ @st.cache_resource
55
+ def prepare_face_app():
56
+ app = FaceAnalysis(name='buffalo_l')
57
+ app.prepare(ctx_id=0, det_size=(640, 640))
58
+ swapper = insightface.model_zoo.get_model('onix.onnx')
59
+ return app, swapper
60
 
61
  def get_upscale_finegrain(prompt, img_path, upscale_factor):
62
  try:
63
  upscale_client = InferenceClient("fal/AuraSR-v2", hf_token=HF_TOKEN_UPSCALER)
64
+ result = upscale_client.predict(input_image=open(img_path, "rb").read(), prompt=prompt, upscale_factor=upscale_factor)
65
  return result[1] if isinstance(result, list) and len(result) > 1 else None
66
  except Exception as e:
67
  st.error(f"Error al mejorar la imagen: {e}")
68
  return None
69
 
70
+ def cleanup_old_images(max_age_days=AppConfig.CLEANUP_DAYS):
71
+ current_time = time.time()
72
+ for image_file in DATA_PATH.glob("*.jpg"):
73
+ if current_time - image_file.stat().st_mtime > max_age_days * 86400:
74
+ os.remove(image_file)
75
+
76
  def authenticate_user(username, password):
77
  return username == credentials["username"] and password == credentials["password"]
78
 
79
  def list_saved_images():
80
+ return sorted(DATA_PATH.glob("*.jpg"), key=lambda x: x.stat().st_mtime, reverse=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  def sort_faces(faces):
83
  return sorted(faces, key=lambda x: x.bbox[0])
 
99
 
100
  def generate_image(prompt, width, height, seed, model_name):
101
  try:
102
+ with st.spinner("Generando imagen..."):
103
+ seed = int(seed) if seed != -1 else random.randint(0, MAX_SEED)
104
+ image = client.text_to_image(
105
+ prompt=prompt,
106
+ height=height,
107
+ width=width,
108
+ model=model_name,
109
+ seed=seed
110
+ )
111
+ return image, seed
112
  except Exception as e:
113
  st.error(f"Error al generar imagen: {e}")
 
 
114
  return None, seed
115
 
116
  def display_gallery():
 
131
  os.remove(image_file)
132
  st.success("Imagen borrada")
133
  display_gallery()
 
 
 
 
134
 
135
+ def save_prompt(image_name, prompt):
136
  with open(DATA_PATH / "prompts.txt", "a") as f:
137
+ f.write(f"{image_name}: {prompt[:100]}\n")
138
+
139
+ def enhance_prompt(text):
140
+ try:
141
+ enhanced = client.text_generation(
142
+ "With this text, generate a descriptive and photorealistic txt2img prompt in English in 200 characters maximum: " + text,
143
+ model="mistralai/Mixtral-8x7B-v0.1",
144
+ max_length=200
145
+ )
146
+ return enhanced[:100]
147
+ except:
148
+ return text[:100]
149
 
150
+ def generate_variations(prompt, num_variants=8, use_enhanced=True):
151
+ instructions = [
152
+ "Create a photorealistic description for a detailed txt2img prompt in English: ",
153
+ "Write a creative, realistic, and detailed text-to-image prompt in English: ",
154
+ "Generate a descriptive and true to life txt2img prompt in English: ",
155
+ "Describe a photorealistic scene with detailed illumination for a txt2img prompt: ",
156
+ "Give a realistic, elegant txt2img prompt in English, emphasizing photorealism: ",
157
+ "Create a visually dynamic and hyperrealistic txt2img prompt in English: ",
158
+ "Write a cinematic txt2img prompt in English with hyperrealistic elements: ",
159
+ "Make a lifelike txt2img prompt in English, focusing on photorealistic depth: "
160
+ ]
161
+
162
  if use_enhanced:
163
+ prompts = []
164
+ for i in range(num_variants):
165
+ instruction = instructions[i % len(instructions)]
166
+ enhanced_prompt = enhance_prompt(f"{instruction}{prompt}")
167
+ prompts.append(enhanced_prompt)
 
 
 
 
 
 
 
 
 
 
 
168
  else:
169
+ prompts = [prompt] * num_variants
170
+ return prompts
171
 
172
+ def gen(prompts, width, height, model_name, num_variants=8):
173
  images = []
174
  seeds = []
175
 
176
  while len(seeds) < num_variants:
177
+ seed = random.randint(0, MAX_SEED)
178
+ if seed not in seeds:
179
+ seeds.append(seed)
180
 
181
+ for i in range(num_variants):
182
+ current_prompt = prompts[i] if len(prompts) > i else prompts[-1]
183
+ with st.spinner(f"Generando imagen {i+1}/{num_variants}"):
184
+ image, used_seed = generate_image(current_prompt, width, height, seeds[i], model_name)
 
 
 
185
  if image:
186
+ image_path = DATA_PATH / f"generated_image_{used_seed}.jpg"
187
+ image.save(image_path)
188
+ save_prompt(f"generated_image_{used_seed}.jpg", current_prompt)
189
+ images.append(str(image_path))
190
+ st.success(f"Imagen {i+1} generada")
 
 
 
191
 
192
  return images
193
 
194
  def get_prompt_for_image(image_name):
 
195
  try:
196
  with open(DATA_PATH / "prompts.txt", "r") as f:
197
  for line in f:
198
  if line.startswith(image_name):
199
+ return line.split(": ", 1)[1].strip()
 
 
 
 
 
200
  except FileNotFoundError:
201
+ return "No hay prompt asociado"
202
+ return "No hay prompt asociado"
203
 
204
  def login_form():
205
  st.title("Iniciar Sesi贸n")
206
  username = st.text_input("Usuario", value="admin")
207
+ password = st.text_input("Contrase帽a", value="flux3", type="password")
208
  if st.button("Iniciar Sesi贸n"):
209
  if authenticate_user(username, password):
 
210
  st.session_state['authenticated'] = True
211
+ st.success("Autenticaci贸n exitosa.")
212
  else:
213
  st.error("Credenciales incorrectas. Intenta de nuevo.")
214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  def upload_image_to_gallery():
216
  uploaded_image = st.sidebar.file_uploader("Sube una imagen a la galer铆a", type=["jpg", "jpeg", "png"])
217
  if uploaded_image:
218
  image = Image.open(uploaded_image)
219
+ image_path = DATA_PATH / uploaded_image.name
220
+ image.save(image_path)
221
+ save_prompt(uploaded_image.name, "uploaded by user")
222
+ st.sidebar.success(f"Imagen subida: {image_path}")
223
+
224
+ app, swapper = prepare_face_app()
225
 
226
  def main():
227
  st.set_page_config(layout="wide")
228
  if 'authenticated' not in st.session_state or not st.session_state['authenticated']:
229
  login_form()
230
  return
231
+
232
  st.title("Flux +Upscale +Prompt Enhancer +FaceSwap")
233
  generated_image_path = st.session_state.get('generated_image_path')
234
  prompt = st.sidebar.text_area("Descripci贸n de la imagen", height=150, max_chars=500)