File size: 7,732 Bytes
f693d07
 
 
1b79b22
 
dab26d7
1b79b22
d7bca1e
00f16cd
1b79b22
 
 
 
 
2234902
4babdf6
1b79b22
c7433ee
d7bca1e
c7433ee
 
2234902
c7433ee
 
 
 
d7bca1e
0eea6c7
ea513a8
 
0ad1714
1b79b22
 
4babdf6
1b79b22
d7bca1e
1b79b22
0ad1714
 
1b79b22
d7bca1e
0ad1714
1b79b22
 
 
4babdf6
1b79b22
 
520d65e
1b79b22
 
4babdf6
1b79b22
 
0ad1714
1b79b22
 
 
d7bca1e
 
 
1b79b22
 
 
 
 
 
 
 
d7bca1e
4babdf6
1b79b22
 
d7bca1e
 
0ad1714
1b79b22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d7bca1e
0ad1714
4babdf6
 
d7bca1e
1b79b22
d7bca1e
8159177
d7bca1e
 
 
1b79b22
8159177
d7bca1e
 
1b79b22
 
d7bca1e
0ad1714
 
4babdf6
 
 
 
 
1b79b22
 
 
 
 
 
d7bca1e
 
1b79b22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73e89e9
0ad1714
 
 
1b79b22
0ad1714
 
 
d7bca1e
1b79b22
0ad1714
 
 
 
 
 
d7bca1e
 
 
 
 
d99c194
1b79b22
0ad1714
5981fd1
1b79b22
 
 
 
 
 
 
0ad1714
 
520d65e
0ad1714
 
 
4babdf6
7d0d952
 
 
1b79b22
4babdf6
1b79b22
 
 
 
 
 
7d0d952
 
 
0ad1714
 
90986f4
7d0d952
4babdf6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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": ""}

@dataclass
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"])
    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 st.sidebar.button("Generar Im谩genes"):
        if prompt:
            prompts = generate_variations(prompt, num_variants=num_variants, use_enhanced=prompt_enhance)
            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)
        else:
            st.warning("Por favor, ingrese una descripci贸n de imagen")
        
    upload_image_to_gallery()
    display_gallery()

if __name__ == "__main__":
    main()