Spaces:
Sleeping
Sleeping
from pathlib import Path | |
from PIL import Image | |
import streamlit as st | |
import os, random, numpy as np, yaml, time | |
from dataclasses import dataclass | |
from typing import List | |
from huggingface_hub import InferenceClient | |
st.set_page_config(layout="wide") | |
HF_TOKEN = os.getenv("HF_TOKEN") | |
if not HF_TOKEN: | |
st.error("Error en el token! 'HF_TOKEN'.") | |
st.stop() | |
try: | |
with open("config.yaml", "r") as file: | |
credentials = yaml.safe_load(file) | |
except Exception as e: | |
st.error(f"Error al cargar el archivo de configuraci贸n: {e}") | |
credentials = {"username": "", "password": ""} | |
class AppConfig: | |
MAX_SEED: int = 1000000 | |
CLEANUP_DAYS: int = 7 | |
MAX_SEED = AppConfig.MAX_SEED | |
DATA_PATH = Path("./data") | |
DATA_PATH.mkdir(exist_ok=True) | |
def get_inference_client(): | |
return InferenceClient(token=HF_TOKEN) | |
client = get_inference_client() | |
def authenticate_user(username, password): | |
return username == credentials["username"] and password == credentials["password"] | |
def list_saved_images(): | |
return sorted(DATA_PATH.glob("*.jpg"), key=lambda x: x.stat().st_mtime, reverse=True) | |
def enhance_prompt(text, client=client): | |
if not client: | |
return text[:200] | |
try: | |
enhanced = client.text_generation( | |
"Generate a photorealistic, detailed txt2img prompt: " + text, | |
model="mistralai/Mixtral-8x7B-Instruct-v0.1",) | |
return enhanced[:200] | |
except Exception as e: | |
st.warning(f"Prompt enhancement error: {e}") | |
return text[:200] | |
def save_prompt(image_name, enhanced_prompt): | |
with open(DATA_PATH / "prompts.txt", "a") as f: | |
f.write(f"{image_name}: {enhanced_prompt}\n") | |
def generate_variations(prompt, num_variants=8, use_enhanced=True): | |
instructions = [ | |
"Photorealistic description for txt2img prompt: ", | |
"Creative, realistic text-to-image prompt: ", | |
"Descriptive, true-to-life txt2img prompt: ", | |
"Naturalistic scene with detailed prompt: ", | |
"Realistic, elegant txt2img prompt: ", | |
"Visually dynamic, hyperrealistic prompt: ", | |
"Cinematic txt2img with hyperrealistic elements: ", | |
"Lifelike txt2img, focusing on photorealistic depth: " | |
] | |
if use_enhanced: | |
prompts = [enhance_prompt(f"{instructions[i % len(instructions)]}{prompt}") for i in range(num_variants)] | |
else: | |
prompts = [prompt] * num_variants | |
return prompts | |
def generate_image(prompt, width, height, seed, model_name, client=client): | |
if not client: | |
st.error("No Hugging Face client available") | |
return None, seed, None | |
try: | |
with st.spinner("Generando imagen..."): | |
seed = int(seed) if seed != -1 else random.randint(0, AppConfig.MAX_SEED) | |
enhanced_prompt = enhance_prompt(prompt) | |
image = client.text_to_image( | |
prompt=enhanced_prompt, | |
height=height, | |
width=width, | |
model=model_name, | |
seed=seed | |
) | |
return image, seed, enhanced_prompt | |
except Exception as e: | |
st.error(f"Image generation error: {e}") | |
return None, seed, None | |
def gen(prompts, width, height, model_name, num_variants=8): | |
images = [] | |
seeds = [] | |
while len(seeds) < num_variants: | |
seed = random.randint(0, MAX_SEED) | |
if seed not in seeds: | |
seeds.append(seed) | |
for i in range(num_variants): | |
current_prompt = prompts[i] if len(prompts) > i else prompts[-1] | |
with st.spinner(f"Generando imagen {i+1}/{num_variants}"): | |
image, used_seed, enhanced_prompt = generate_image(current_prompt, width, height, seeds[i], model_name) | |
if image: | |
image_path = DATA_PATH / f"generated_image_{used_seed}.jpg" | |
image.save(image_path) | |
save_prompt(f"generated_image_{used_seed}.jpg", enhanced_prompt) | |
images.append((str(image_path), enhanced_prompt)) | |
st.success(f"Imagen {i+1} generada") | |
return images | |
def get_prompt_for_image(image_name): | |
try: | |
with open(DATA_PATH / "prompts.txt", "r") as f: | |
for line in f: | |
if line.startswith(image_name): | |
original_prompt = line.split(": ", 1)[1].strip() | |
image_path = DATA_PATH / image_name | |
if image_path.exists(): | |
return original_prompt | |
except FileNotFoundError: | |
return "No hay prompt asociado" | |
return "No hay prompt asociado" | |
def display_gallery(): | |
st.header("Galer铆a de Im谩genes Guardadas") | |
images = list_saved_images() | |
if images: | |
cols = st.columns(4) | |
for i, image_file in enumerate(images): | |
with cols[i % 4]: | |
st.image(str(image_file), use_column_width=True) | |
prompt = get_prompt_for_image(image_file.name) | |
st.caption(prompt[:250]) | |
if st.button(f"Borrar", key=f"delete_{i}_{image_file}"): | |
if image_file.exists(): | |
os.remove(image_file) | |
st.success("Imagen borrada") | |
st.rerun() | |
def login_form(): | |
st.title("Iniciar Sesi贸n") | |
username = st.text_input("Usuario", value="admin") | |
password = st.text_input("Contrase帽a", value="flux3x", type="password") | |
if st.button("Iniciar Sesi贸n"): | |
if authenticate_user(username, password): | |
st.session_state['authenticated'] = True | |
st.success("Autenticaci贸n exitosa.") | |
else: | |
st.error("Credenciales incorrectas. Intenta de nuevo.") | |
def upload_image_to_gallery(): | |
uploaded_image = st.sidebar.file_uploader("Sube una imagen a la galer铆a", type=["jpg", "jpeg", "png"]) | |
if uploaded_image: | |
image = Image.open(uploaded_image) | |
image_path = DATA_PATH / uploaded_image.name | |
image.save(image_path) | |
save_prompt(uploaded_image.name, "uploaded by user") | |
st.sidebar.success(f"Imagen subida: {image_path}") | |
def main(): | |
if 'authenticated' not in st.session_state or not st.session_state['authenticated']: | |
login_form() | |
return | |
st.title("Flux +Upscale +Prompt Enhancer") | |
if not client: | |
st.error("No se pudo establecer conexi贸n con Hugging Face. Verifique sus tokens.") | |
return | |
prompt = st.sidebar.text_area("Descripci贸n de la imagen", height=150, max_chars=500) | |
format_option = st.sidebar.selectbox("Formato", ["9:16", "16:9", "1:1"]) | |
model_option = st.sidebar.selectbox("Modelo", ["black-forest-labs/FLUX.1-schnell", "black-forest-labs/FLUX.1-dev"]) | |
prompt_enhance = st.sidebar.checkbox("Mejorar Prompt", True) | |
num_variants = st.sidebar.slider("N煤mero de im谩genes", 1, 8, 8) | |
width, height = (720, 1280) if format_option == "9:16" else (1280, 720) if format_option == "16:9" else (1280, 1280) | |
if prompt: | |
prompts = generate_variations(prompt, num_variants=num_variants, use_enhanced=prompt_enhance) | |
if st.sidebar.button("Generar Im谩genes"): | |
generated_images = gen(prompts, width, height, model_option, num_variants) | |
st.header("Im谩genes Generadas") | |
cols = st.columns(4) | |
for i, (image_path, image_prompt) in enumerate(generated_images): | |
with cols[i % 4]: | |
st.image(image_path, use_column_width=True) | |
st.caption(image_prompt) | |
upload_image_to_gallery() | |
display_gallery() | |
if __name__ == "__main__": | |
main() |