Spaces:
Running
Running
Josue Aaron Soriano Rivero
commited on
Commit
·
4c25e18
0
Parent(s):
Estructura inicial del proyecto WaifuCreator
Browse files- .gitignore +41 -0
- app.py +90 -0
- model.py +17 -0
- requirements.txt +0 -0
- translations.py +45 -0
- utils.py +30 -0
.gitignore
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Environments
|
2 |
+
.env
|
3 |
+
.venv
|
4 |
+
env/
|
5 |
+
venv/
|
6 |
+
ENV/
|
7 |
+
env.bak/
|
8 |
+
venv.bak/
|
9 |
+
|
10 |
+
comando.txt
|
11 |
+
|
12 |
+
# Archivos y carpetas de Gradio
|
13 |
+
.gradio/
|
14 |
+
|
15 |
+
# Archivos compilados de Python
|
16 |
+
__pycache__/
|
17 |
+
*.pyc
|
18 |
+
*.pyo
|
19 |
+
*.pyd
|
20 |
+
|
21 |
+
# Entornos virtuales
|
22 |
+
venv/
|
23 |
+
.env/
|
24 |
+
.venv/
|
25 |
+
|
26 |
+
# Archivos de configuración específicos del IDE
|
27 |
+
.vscode/
|
28 |
+
.idea/
|
29 |
+
|
30 |
+
# Archivos de logs y temporales
|
31 |
+
*.log
|
32 |
+
*.tmp
|
33 |
+
|
34 |
+
# Archivos sensibles
|
35 |
+
.env
|
36 |
+
config.json
|
37 |
+
secrets.json
|
38 |
+
|
39 |
+
# Otros archivos generados por el sistema
|
40 |
+
.DS_Store
|
41 |
+
Thumbs.db
|
app.py
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from model import get_device, load_model
|
3 |
+
from utils import build_prompt, generate_image
|
4 |
+
from translations import TRANSLATIONS
|
5 |
+
|
6 |
+
device = get_device()
|
7 |
+
pipe = load_model(device)
|
8 |
+
|
9 |
+
def create_interface():
|
10 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
11 |
+
gr.Markdown("""
|
12 |
+
<div style="text-align: center; margin-bottom: 30px;">
|
13 |
+
<h1 style="font-size: 2.5em; color: #4F46E5; font-weight: bold;">🎨Retrato WaifuStudio</h1>
|
14 |
+
<h3 style="color: #6B7280;">Genera fotos de perfil estilo anime totalmente personalizables</h3>
|
15 |
+
<p style="font-size: 0.9em; color: #9CA3AF; margin-top: 20px;">Si disfrutas de esta herramienta y deseas apoyar su desarrollo continuo, considera realizar una donación sin restricciones para contribuir a futuras mejoras, incluyendo la posibilidad de generar contenido sin limitaciones, tanto creativo como explícito.</p>
|
16 |
+
<a href="https://paypal.me/srjosuearon?country.x=MX&locale.x=es_XC" style="font-size: 1em; color: #4F46E5; text-decoration: underline;">Apoya con una donación</a>
|
17 |
+
</div>
|
18 |
+
""")
|
19 |
+
|
20 |
+
user_inputs = {}
|
21 |
+
|
22 |
+
with gr.Row():
|
23 |
+
with gr.Column():
|
24 |
+
for category, options in TRANSLATIONS.items():
|
25 |
+
with gr.Accordion(category, open=False):
|
26 |
+
user_inputs[category] = gr.CheckboxGroup(
|
27 |
+
options, label=category
|
28 |
+
)
|
29 |
+
|
30 |
+
with gr.Column():
|
31 |
+
with gr.Row():
|
32 |
+
clear_button = gr.Button("🧹 Limpiar texto")
|
33 |
+
generate_button = gr.Button("🚀 Generar Imagen")
|
34 |
+
|
35 |
+
prompt_output = gr.Textbox(label="📝 Características de la imagen", interactive=True)
|
36 |
+
image_output = gr.Image(label="📥 Imagen generada")
|
37 |
+
|
38 |
+
def update_prompt(*args):
|
39 |
+
kwargs = {key: value for key, value in zip(TRANSLATIONS.keys(), args)}
|
40 |
+
return build_prompt(**kwargs)
|
41 |
+
|
42 |
+
def on_generate_image(*args):
|
43 |
+
kwargs = {key: value for key, value in zip(TRANSLATIONS.keys(), args)}
|
44 |
+
prompt = build_prompt(**kwargs)
|
45 |
+
image = generate_image(prompt, pipe, device)
|
46 |
+
return prompt, image
|
47 |
+
|
48 |
+
def clear_fields():
|
49 |
+
return ([],) * len(TRANSLATIONS) + ("",)
|
50 |
+
|
51 |
+
for input_component in user_inputs.values():
|
52 |
+
input_component.change(
|
53 |
+
fn=update_prompt,
|
54 |
+
inputs=list(user_inputs.values()),
|
55 |
+
outputs=prompt_output
|
56 |
+
)
|
57 |
+
|
58 |
+
clear_button.click(
|
59 |
+
fn=clear_fields,
|
60 |
+
inputs=[],
|
61 |
+
outputs=list(user_inputs.values()) + [prompt_output]
|
62 |
+
)
|
63 |
+
|
64 |
+
generate_button.click(
|
65 |
+
fn=on_generate_image,
|
66 |
+
inputs=list(user_inputs.values()),
|
67 |
+
outputs=[prompt_output, image_output]
|
68 |
+
)
|
69 |
+
|
70 |
+
gr.HTML("""
|
71 |
+
<div style="position: fixed; bottom: 20px; right: 20px; z-index: 1000;">
|
72 |
+
<button onclick="window.scrollTo({ top: 0, behavior: 'smooth' });"
|
73 |
+
style="background-color: #4CAF50; color: white; border: none; padding: 10px 20px;
|
74 |
+
border-radius: 5px; cursor: pointer; font-size: 14px;">
|
75 |
+
⬆ Volver al Inicio
|
76 |
+
</button>
|
77 |
+
</div>
|
78 |
+
""")
|
79 |
+
|
80 |
+
gr.HTML("""
|
81 |
+
<footer style="text-align: center; margin-top: 50px; padding: 20px; background-color: #f9fafb; border-top: 1px solid #e5e7eb; font-size: 0.9em; color: #6b7280;">
|
82 |
+
<p>© 2024 WaifuCreator. Usando el modelo Waifu Diffusion de <a href="https://huggingface.co/hakurei/waifu-diffusion" style="font-size: 1em; color: #4F46E5; text-decoration: underline;">Hakurei</a></p>
|
83 |
+
<p>Desarrollado con ❤️ por <a href="https://www.linkedin.com/in/srjosueaaron" style="font-size: 1em; color: #4F46E5; text-decoration: underline;">@srjosueaaron</a></p>
|
84 |
+
</footer>
|
85 |
+
""")
|
86 |
+
return demo
|
87 |
+
|
88 |
+
# Lanzar la interfaz
|
89 |
+
demo = create_interface()
|
90 |
+
demo.launch(debug=True)
|
model.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# model.py
|
2 |
+
import torch
|
3 |
+
from diffusers import StableDiffusionPipeline
|
4 |
+
|
5 |
+
def get_device():
|
6 |
+
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
7 |
+
print(f"Usando dispositivo: {device}")
|
8 |
+
return device
|
9 |
+
|
10 |
+
def load_model(device):
|
11 |
+
pipe = StableDiffusionPipeline.from_pretrained(
|
12 |
+
'hakurei/waifu-diffusion',
|
13 |
+
torch_dtype=torch.float16 if device == 'cuda' else torch.float32,
|
14 |
+
variant="fp16" if device == 'cuda' else None
|
15 |
+
).to(device)
|
16 |
+
pipe.safety_checker = None
|
17 |
+
return pipe
|
requirements.txt
ADDED
Binary file (2.33 kB). View file
|
|
translations.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
TRANSLATIONS = {
|
2 |
+
"Colores de cabello": ["cabello negro", "cabello rubio", "cabello castaño", "cabello rojo", "cabello blanco", "cabello azul", "cabello azul claro", "cabello azul oscuro", "cabello verde", "cabello gris", "cabello rosa", "cabello rosa claro", "cabello rosa oscuro", "cabello púrpura", "cabello naranja", "cabello aguamarina"],
|
3 |
+
"Peinados": ["corte bob", "corte pixie", "corte rapado", "corte militar", "corte tazón", "corte plano", "corte bajo", "corte lobo", "cabello volteado", "cabello ondulado", "corte medusa", "corte hime", "mullet", "trenzas africanas", "rastas"],
|
4 |
+
"Textura del cabello": ["cabello liso", "cabello ondulado", "cabello rizado", "cabello despeinado", "cabello puntiagudo", "cabello afilado", "rizos", "cabello perforado", "mechones sueltos"],
|
5 |
+
"Emociones": ["feliz", "enojado", "sonrojado", "emocionado", "triste", "nervioso", "asustado", "serio", "confundido", "aburrido", "molesto", "decepcionado", "decidido", "pensativo", "mueca", "agotado", "solitario", "boca abierta", "ojos cerrados", "ceja levantada", "loco", "ebrio", "disgustado"],
|
6 |
+
"Colores individuales del iris": ["ojos azules", "ojos marrones", "ojos verdes", "ojos morados", "ojos rojos", "ojos amarillos", "ojos aguamarina", "ojos negros", "ojos naranjas", "ojos rosados", "ojos blancos", "ojos grises", "ojos ámbar"],
|
7 |
+
"Colores de las pupilas": ["pupilas azules", "pupilas verdes", "pupilas rojas", "pupilas amarillas", "pupilas aguamarina", "pupilas naranjas", "pupilas rosadas", "pupilas moradas", "pupilas blancas"],
|
8 |
+
"Estilos de ojos": ["ojos brillantes", "ojos de círculo sólido", "ojos en forma de corazón", "ojos locos", "ojos vacíos", "tareme", "tsurime", "jitome", "sanpaku"],
|
9 |
+
"Esclerótica": ["esclerótica blanca", "esclerótica negra", "esclerótica roja", "esclerótica azul", "esclerótica verde", "esclerótica amarilla", "esclerótica naranja", "ojos vacíos", "ojos inyectados en sangre", "sin esclerótica"],
|
10 |
+
"Alrededor de los ojos": ["ojeras", "aegyo sal", "ojos brillando", "ojos en llamas", "ojo morado"],
|
11 |
+
"Accesorios para los ojos": ["parche en el ojo", "cabello sobre un ojo", "cabello sobre los ojos", "venda sobre un ojo", "cubriéndose los ojos", "ojos visibles a través del cabello"],
|
12 |
+
"Gafas": ["gafas de sol", "gafas sin montura", "gafas pequeñas", "gafas de botella", "gafas cómicas", "gafas sin lentes"],
|
13 |
+
"Orejas de animales": ["orejas de gato", "orejas de zorro", "orejas de perro", "orejas de conejo", "orejas de lobo", "orejas de oso", "orejas de ciervo", "orejas de murciélago", "orejas de vaca", "orejas de cabra", "orejas de león", "orejas de mono", "orejas de ratón", "orejas de caballo", "orejas de pikachu"],
|
14 |
+
"Auriculares": ["auriculares con orejas de gato", "auriculares con orejas de conejo", "auriculares en el cuello", "auriculares para orejas de animales", "auricular", "diadema", "auricular de oído", "auriculares detrás de la cabeza"],
|
15 |
+
"Sombreros": ["sombrero de paja", "sombrero pescador", "sombrero vaquero", "gorra de béisbol", "bombín", "gorra plana", "sombrero caballero", "sombrero detective", "gorra con visera", "gorro shako", "gorra de conductor", "bicorne", "gat (sombrero)", "jingasa", "gorro mob"],
|
16 |
+
"Estilos de sombreros no específicos": ["sombrero escolar", "sombrero de policía", "sombrero militar", "gorra de campaña", "gorra mao", "gorra m43", "rogatywka", "sombrero de camuflaje"],
|
17 |
+
"Coronas": ["tiara", "mini corona", "aro ornamental", "diadema", "saishi", "fengguan", "mian guan"],
|
18 |
+
"Cascos": ["casco de motocicleta", "casco tipo pecera", "casco de buceo", "casco de obra", "casco con lámpara", "casco de fútbol americano", "casco de béisbol", "casco colonial", "casco sallet", "yelmo", "casco con cuernos"],
|
19 |
+
"Casco de combate": ["casco con alas", "stahlhelm", "casco brodie", "casco altyn", "casco adrian", "casco de combate"],
|
20 |
+
"Colores de fondo": ["fondo azul", "fondo rosa", "fondo morado", "fondo rojo", "fondo blanco", "fondo negro", "fondo gris", "fondo verde", "fondo amarillo", "fondo aguamarina", "fondo naranja", "fondo marrón"],
|
21 |
+
"Patrones de fondo": ["fondo simple", "fondo a cuadros", "fondo de lunares", "fondo de cuadrícula", "fondo de rombos", "fondo punteado", "fondo de cruces", "fondo de tartán", "fondo de rayos solares", "fondo en espiral", "fondo de fresas", "fondo de copos de nieve", "fondo de huellas", "fondo temático de comida"]
|
22 |
+
}
|
23 |
+
|
24 |
+
CATEGORIES = {
|
25 |
+
"Colores de cabello": ["black hair", "blonde hair", "brown hair", "red hair", "white hair", "blue hair", "light blue hair", "dark blue hair", "green hair", "grey hair", "pink hair", "light pink hair", "dark pink hair", "purple hair", "orange hair", "aqua hair"],
|
26 |
+
"Peinados": ["bob cut", "pixie cut", "buzz cut", "crew cut", "bowl cut", "flattop", "undercut", "wolf cut", "flipped hair", "hair flip", "jellyfish cut", "hime cut", "mullet", "cornrows", "dreadlocks"],
|
27 |
+
"Textura del cabello": ["straight hair", "wavy hair", "curly hair", "messy hair", "spiked hair", "pointy hair", "ringlets", "drill hair", "hair flaps"],
|
28 |
+
"Emociones": ["happy", "angry", "blush", "excited", "sad", "nervous", "scared", "serious", "confused", "bored", "annoyed", "disappointed", "determined", "thinking", "grimace", "exhausted", "lonely", "open mouth", "closed eyes", "raised eyebrow", "crazy", "drunk", "disgust"],
|
29 |
+
"Colores individuales del iris": ["blue eyes", "brown eyes", "green eyes", "purple eyes", "red eyes", "yellow eyes", "aqua eyes", "black eyes", "orange eyes", "pink eyes", "white eyes", "grey eyes", "amber eyes"],
|
30 |
+
"Colores de las pupilas": ["blue pupils", "green pupils", "red pupils", "yellow pupils", "aqua pupils", "orange pupils", "pink pupils", "purple pupils", "white pupils"],
|
31 |
+
"Estilos de ojos": ["sparkling eyes", "solid circle eyes", "heart-shaped eyes", "crazy eyes", "empty eyes", "tareme", "tsurime", "jitome", "sanpaku"],
|
32 |
+
"Esclerótica": ["white sclera", "black sclera", "red sclera", "blue sclera", "green sclera", "yellow sclera", "orange sclera", "blank eyes", "bloodshot eyes", "no sclera"],
|
33 |
+
"Alrededor de los ojos": ["bags under eyes", "aegyo sal", "glowing eyes", "flaming eyes", "bruised eye"],
|
34 |
+
"Accesorios para los ojos": ["eyepatch", "hair over one eye", "hair over eyes", "bandage over one eye", "covering own eyes", "eyes visible through hair"],
|
35 |
+
"Gafas": ["sunglasses", "rimless eyewear", "mini eyewear", "coke-bottle glasses", "groucho glasses", "lensless glasses"],
|
36 |
+
"Orejas de animales": ["cat ears", "fox ears", "dog ears", "rabbit ears", "wolf ears", "bear ears", "deer ears", "bat ears", "cow ears", "goat ears", "lion ears", "monkey ears", "mouse ears", "horse ears", "pikachu ears"],
|
37 |
+
"Auriculares": ["cat ear headphones", "bunny headphones", "headphones around neck", "headphones for animal ears", "headphone", "headset", "earpiece", "behind-the-head headphones"],
|
38 |
+
"Sombreros": ["straw hat", "bucket hat", "cowboy hat", "baseball cap", "bowler hat", "flat cap", "cavalier hat", "deerstalker", "peaked cap", "shako cap", "cabbie hat", "bicorne", "gat (hat)", "jingasa", "mob cap"],
|
39 |
+
"Estilos de sombreros no específicos": ["school hat", "police hat", "military hat", "field cap", "mao cap", "m43 field cap", "rogatywka", "camouflage headwear"],
|
40 |
+
"Coronas": ["tiara", "mini crown", "circlet", "diadem", "saishi", "fengguan", "mian guan"],
|
41 |
+
"Cascos": ["motorcycle helmet", "fishbowl helmet", "diving helmet", "hard hat", "headlamp", "american football helmet", "baseball helmet", "pith helmet", "sallet", "helm", "horned helmet"],
|
42 |
+
"Casco de combate": ["winged helmet", "stahlhelm", "brodie helmet", "altyn helmet", "adrian helmet", "combat_helmet"],
|
43 |
+
"Colores de fondo": ["blue background", "pink background", "purple background", "red background", "white background", "black background", "grey background", "green background", "yellow background", "aqua background", "orange background", "brown background"],
|
44 |
+
"Patrones de fondo": ["simple background", "checkered background", "polka dot background", "grid background", "argyle background", "dotted background", "cross background", "plaid background", "sunburst background", "spiral background", "strawberry background", "snowflake background", "paw print background", "food-themed background"]
|
45 |
+
}
|
utils.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
from torch.cuda.amp import autocast
|
3 |
+
from translations import CATEGORIES, TRANSLATIONS
|
4 |
+
|
5 |
+
def build_prompt(**kwargs):
|
6 |
+
default_params = ["masterpiece", "best quality", "1girl", "watercolor", "portrait", "upper body", "looking at viewer", "anime screenshot", "highres"]
|
7 |
+
|
8 |
+
for key, values in kwargs.items():
|
9 |
+
if values:
|
10 |
+
english_values = [CATEGORIES[key][TRANSLATIONS[key].index(v)] for v in values if v in TRANSLATIONS[key]]
|
11 |
+
default_params.append(", ".join(english_values))
|
12 |
+
|
13 |
+
return ', '.join(default_params)
|
14 |
+
|
15 |
+
def generate_image(prompt, pipe, device):
|
16 |
+
height = 512
|
17 |
+
width = 512
|
18 |
+
guidance_scale = 15
|
19 |
+
num_inference_steps = 50
|
20 |
+
pipe.enable_attention_slicing()
|
21 |
+
|
22 |
+
with torch.autocast('cuda') if device == 'cuda' else torch.inference_mode():
|
23 |
+
image = pipe(
|
24 |
+
prompt,
|
25 |
+
guidance_scale=guidance_scale,
|
26 |
+
num_inference_steps=num_inference_steps,
|
27 |
+
height=height,
|
28 |
+
width=width
|
29 |
+
).images[0]
|
30 |
+
return image
|