File size: 15,759 Bytes
0c6331e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
importare il sistema operativo
importa casuale
importa sys
dalla digitazione import  Sequenza , Mappatura, Qualsiasi , Unione
torcia di importazione
importa gradio come gr
da PIL importa Immagine
importa numpy come np
da huggingface_hub importa hf_hub_download
spazi di importazione
da comfy import model_management

CHROMA_VERSION = "chroma-unlocked-v34.safetensors"

# Scarica i modelli richiesti
t5_path = hf_hub_download(repo_id= "comfyanonymous/flux_text_encoders" , filename= "t5xxl_fp8_e4m3fn.safetensors" , local_dir= "modelli/text_encoders/" )
vae_path = hf_hub_download(repo_id= "lodestones/Chroma" , filename= "ae.safetensors" , local_dir= "modelli/vae" )
unet_path = hf_hub_download(repo_id= "lodestones/Chroma" , filename=CHROMA_VERSION, local_dir= "modelli/unet" )

# Esempi di prompt con i relativi parametri
ESEMPI = [
    [
        Un ritratto ravvicinato di alta moda di una donna bionda con occhiali da sole trasparenti. L'immagine utilizza una decisa combinazione di verde acqua e rosso per un'illuminazione spettacolare. Lo sfondo è un semplice verde acqua. La foto è nitida e ben composta, ed è progettata per la visualizzazione con occhiali 3D anaglifici per un effetto ottimale. Sembra realizzata da un professionista .
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 36 , 3.0 , 229
    ],
    [
        Un giovane sorride ampiamente mentre indossa un cappello da capitano blu e occhiali da sole aviator blu a specchio. L'uomo è il fulcro dell'immagine, su uno sfondo di lungomare piacevolmente sfocato con barche ed edifici. Lo scatto è allegro, giocoso e dall'aspetto amatoriale.
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 40 , 2.1 , 424
    ],
    [
        Uno Shiba Inu sorride ampiamente mentre indossa un cappello da capitano blu e occhiali da sole aviatore blu a specchio. Il cane è il fulcro dell'immagine, su uno sfondo di lungomare piacevolmente sfocato con barche ed edifici. Lo scatto è allegro, giocoso e dall'aspetto amatoriale.
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 28 , 2.9 , 413
    ],
    [
        Un dipinto raffigura un uomo barbuto con una camicia beige che stringe una cima su una barca a vela, mentre affronta mari agitati sotto un tramonto spettacolare. Un'altra figura appare sullo sfondo in lontananza, e lo stile è impressionista, con pennellate nitide e grande maestria. L'effetto complessivo è di avventura e libertà .
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 33 , 4.6 , 281
    ],
    [
        Un dipinto mostra un lupo maschio antropomorfo seduto su una roccia in una foresta, antropomorfo, maschio, solitario, canino, canide, lupo mannaro, antropomorfo muscoloso, corpo nero, pelliccia nera, che allunga le zampe verso l'osservatore, sfondo dettagliato, esterno. La scena è dettagliata, con una ridotta profondità di campo che si concentra sul lupo antropomorfo. L'effetto generale è fantasy e cinematografico .
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 26 , 3,8 , 326
    ],
    [
        "Una simpatica illustrazione in stile cartoon di un enorme drago nero con ali che riproducono galassie cosmiche, seduto in cima a un castello che domina una città portuale medievale al tramonto. Lo stile è luminoso e dai toni pastello, con linee morbide. L'opera è pulita e piuttosto ben realizzata. "
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 41 , 5.7 , 244
    ],
    [
        Un cane maschio antropomorfo a pelo lungo, con una macchia bianca sul petto e brillanti occhi giallo-verdi, è seduto su un'isola grigio chiaro della cucina in un appartamento di New York inondato di sole. La vista della città è sfocata, mostrando una ridotta profondità di campo . Il gatto ha un collare scuro con un piccolo campanellino. L'estetica della foto è pulita, moderna e leggermente drammatica grazie all'illuminazione.
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 26 , 4.7 , 242
    ],
    [
        Un allegro collage mostra 4 gechi leopardo, ognuno in un riquadro separato. I gechi variano per colore e motivo, ma sono tutti ritratti in primo piano e con lo sguardo rivolto direttamente alla fotocamera. Gli sfondi sono diversi, illustrando vari elementi del terrario e superfici semplici. Scatti di alta qualità, illuminazione brillante, qualità fotografica amatoriale. L'estetica generale è semplice e commovente .
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 26 , 4.7 , 249
    ],
    [
        Un allegro collage presenta 4 simpatici peluche di Nick Wilde, raffiguranti il ​​lupo antropomorfo, ognuno in un quadrato separato. Gli sfondi sono diversi, raffigurando vari letti e superfici semplici. Scatti di alta qualità, illuminazione brillante, qualità fotografica amatoriale. L'estetica generale è semplice e commovente .
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 26 , 5.4 , 263
    ],
    [
        "questa immagine raffigura un adesivo di un telegramma con spessi contorni bianchi di una volpe antropomorfa maschio" ,
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 28 , 3.9 , 399
    ],
    [
        "Estremamente ravvicinato di un singolo occhio di tigre, vista frontale diretta. Iride e pupilla dettagliate. Messa a fuoco nitida sulla texture e sul colore dell'occhio. Illuminazione naturale per catturare la brillantezza e la profondità autentiche degli occhi. La parola "Chroma" è dipinta sopra con grandi pennellate bianche con texture visibile. "
        "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
        1024 , 1024 , 26 , 4.0 , 9
    ]
]

# Funzioni di utilità
def  get_value_at_index ( obj: Unione [ Sequenza , Mappatura], indice: int ) -> Qualsiasi :
    Tentativo :
        restituisci obj[indice]
    eccetto KeyError:
        restituisci obj[ "risultato" ][indice]

def  find_path ( nome: str , percorso: str = Nessuno ) -> str :
    se il percorso è  Nessuno :
        percorso = os.getcwd()
    se il nome è in os.listdir(percorso):
        path_name = os.path.join(percorso, nome)
        stampa ( f" {nome} trovato: {nome_percorso} " )
        restituisci il percorso
    directory_genitore = os.path.dirname(percorso)
    se parent_directory == percorso:
        restituisci  Nessuno
    restituisci find_path(nome, directory_padre)

def  add_comfyui_directory_to_sys_path () -> Nessuno :
    comfyui_path = find_path( "ComfyUI" )
    se comfyui_path non è  None e os.path.isdir(comfyui_path):  
        sys.path.append(comfyui_path)
        stampa ( f"' {comfyui_path} ' aggiunto a sys.path" )

def  add_extra_model_paths () -> Nessuno :
    Tentativo :
        dall'importazione principale load_extra_path_config​
    eccetto ImportError:
        da utils.extra_config importa load_extra_path_config
    percorsi_modello_extra = trova_percorso( "percorsi_modello_extra.yaml" )
    se extra_model_paths non è  None : 
        carica_configurazione_percorso_extra(percorsi_modello_extra)
    altro :
        print ( "Impossibile trovare il file di configurazione extra_model_paths." )

def  import_custom_nodes () -> Nessuno :
    importa asyncio
    esecuzione dell'importazione
    da nodi importa init_extra_nodes
    server di importazione
    ciclo = asyncio.new_event_loop()
    asyncio.set_event_loop(ciclo)
    istanza_server = server.PromptServer(ciclo)
    esecuzione.PromptQueue(istanza_server)
    init_extra_nodes()

# Inizializza i percorsi
aggiungi_directory_comfyui_al_percorso_di_sistema()
aggiungi_percorsi_modello_extra()
importa_nodi_personalizzati()

# Importa tutti i nodi necessari
da nodi importa (
    NODE_CLASS_MAPPINGS,
    CLIPTextEncode,
    CLIPLader,
    VAEDecode,
    Caricatore UNET,
    VAELoader,
    SalvaImmagine,
)

# Inizializza tutti i caricatori di modelli al di fuori della funzione
rumore casuale = NODE_CLASS_MAPPINGS[ "Rumore casuale" ]()
emptysd3latentimage = NODE_CLASS_MAPPINGS[ "EmptySD3LatentImage" ]()
ksamplerselect = NODE_CLASS_MAPPINGS[ "KSamplerSelect" ]()
caricatore di clip = CLIPLoader()
t5tokenizeroptions = NODE_CLASS_MAPPINGS[ "T5TokenizerOptions" ]()
cliptextencode = CLIPTextEncode()
unetloader = UNETLoader()
vaeloader = VAELoader()
cfgguider = NODE_CLASS_MAPPINGS[ "CFGGuider" ]()
basicscheduler = NODE_CLASS_MAPPINGS[ "BasicScheduler" ]()
samplercustomadvanced = NODE_CLASS_MAPPINGS[ "SamplerCustomAdvanced" ]()
vaedecode = VAEDecode()
salvaimmagine = SalvaImmagine()

# Modelli di carico
cliploader_78 = cliploader.load_clip(
    clip_name= "t5xxl_fp8_e4m3fn.safetensors" , tipo = "chroma" , dispositivo = "predefinito"
)
t5tokenizeroptions_82 = t5tokenizeroptions.set_options(
    min_padding= 1 , min_length= 0 , clip=get_value_at_index(cliploader_78, 0 )
)
unetloader_76 = unetloader.load_unet(
    unet_name=VERSIONE_CROMATICA, weight_dtype= "fp8_e4m3fn"
)
vaeloader_80 = vaeloader.load_vae(vae_name= "ae.safetensors" )

# Aggiungi tutti i modelli che caricano un file safetensors
caricatori_modello = [cliploader_78, unetloader_76, vaeloader_80]

# Controlla quali modelli sono validi e come caricarli al meglio
modelli_validi = [
    getattr (caricatore[ 0 ], 'patcher' , caricatore[ 0 ])
    per il caricatore in model_loaders
    se  non è  isinstance (loader[ 0 ], dict ) e  non è  isinstance ( getattr (loader[ 0 ], 'patcher' , None ), dict )
]

# Infine carica i modelli
gestione_modello.carica_modelli_gpu(modelli_validi)

@spazi.GPU
def  generate_image ( prompt, negative_prompt, larghezza, altezza, passaggi, cfg, seed ):
    con torch.inference_mode():
        # Imposta un seme casuale se fornito
        se seme == - 1 :
            seme = random.randint( 1 , 2 ** 64 )
        random.seed(seme)
        
        randomnoise_68 = randomnoise.get_noise(noise_seed=seme)
        emptysd3latentimage_69 = emptysd3latentimage.generate(
            larghezza=larghezza, altezza=altezza, dimensione_lotto= 1
        )
        ksamplerselect_72 = ksamplerselect.get_sampler(sampler_name= "euler" )

        cliptextencode_74 = cliptextencode.encode(
            testo=richiesta,
            clip=ottieni_valore_all'indice(t5tokenizeroptions_82, 0 ),
        )

        cliptextencode_75 = cliptextencode.encode(
            testo=prompt_negativo,
            clip=ottieni_valore_all'indice(t5tokenizeroptions_82, 0 ),
        )

        cfgguider_73 = cfgguider.get_guider(
            cfg=cfg,
            modello=ottieni_valore_all'indice(unetloader_76, 0 ),
            positivo=ottieni_valore_all'indice(cliptextencode_74, 0 ),
            negativo=get_value_at_index(cliptextencode_75, 0 ),
        )

        basicscheduler_84 = basicscheduler.get_sigmas(
            scheduler= "beta" ,
            passi=passi,
            riduzione del rumore = 1 ,
            modello=ottieni_valore_all'indice(unetloader_76, 0 ),
        )

        samplercustomadvanced_67 = samplercustomadvanced.sample(
            rumore=ottieni_valore_all'indice(rumore_casuale_68, 0 ),
            guider=get_value_at_index(cfgguider_73, 0 ),
            campionatore=ottieni_valore_all'indice(ksamplerselect_72, 0 ),
            sigma=ottieni_valore_all'indice(basicscheduler_84, 0 ),
            latent_image=ottieni_valore_all'indice(emptysd3latentimage_69, 0 ),
        )

        vaedecode_79 = vaedecode.decode(
            campioni=ottieni_valore_all'indice(campionatorepersonalizzatoavanzato_67, 0 ),
            vae=ottieni_valore_all'indice(vaeloader_80, 0 ),
        )

        # Salva l'immagine utilizzando il nodo SaveImage con un semplice prefisso di stringa
        salvato = salvaimmagine.salva_immagini(
            prefisso_filename= "Chroma_Generated" ,
            immagini=ottieni_valore_all'indice(vaedecode_79, 0 ),
        )
        
        # Restituisce il percorso all'immagine salvata
        saved_path = f"output/ {saved[ 'ui' ][ 'immagini' ][ 0 ][ 'nomefile' ]} "
        restituisci saved_path

# Crea l'interfaccia Gradio
con gr.Blocks() come app:
    gr.Markdown( """
# Croma
Modello: [Chroma](https://huggingface.co/lodestones/Chroma) di [lodestones](https://huggingface.co/lodestones)
Esegui qualsiasi flusso di lavoro ComfyUI su Spaces: [Flussi di lavoro ComfyUI](https://huggingface.co/blog/run-comfyui-workflows-on-spaces)
Spazio Autore: [GitHub](https://github.com/gokayfem) | [X.com](https://x.com/gokayfem)
    """ )
    
    con gr.Row():
        con gr.Column():
            prompt = gr.Textbox(
                etichetta= "Richiesta" ,
                placeholder= "Inserisci qui il tuo messaggio..." ,
                linee= 3
            )
            negative_prompt = gr.Textbox(
                etichetta= "Prompt negativo" ,
                placeholder= "Inserisci qui il prompt negativo..." ,
                valore = "bassa qualità, brutto, incompiuto, sfocato, deformato, sfigurato, sfocato, macchiato, tavolozza limitata, colori piatti" ,
                linee= 2
            )
            
            con gr.Row():
                larghezza = gr.Slider(
                    minimo= 512 ,
                    massimo= 2048 ,
                    valore= 1024 ,
                    passo= 64 ,
                    etichetta= "Larghezza"
                )
                altezza = gr.Slider(
                    minimo= 512 ,
                    massimo= 2048 ,
                    valore= 1024 ,
                    passo= 64 ,
                    etichetta= "Altezza"
                )
            
            con gr.Row():
                passi = gr.Slider(
                    minimo= 1 ,
                    massimo= 50 ,
                    valore= 26 ,
                    passo= 1 ,
                    etichetta= "Passaggi"
                )
                cfg = gr.Slider(
                    minimo= 1 ,
                    massimo= 20 ,
                    valore= 4 ,
                    passo = 0,5 ,
                    etichetta= "Scala CFG"
                )
                seme = gr.Numero(
                    valore=- 1 ,
                    etichetta= "Seme (-1 per casuale)"
                )
            
            generate_btn = gr.Button( "Genera" )
        
        con gr.Column():
            output_image = gr.Image(label= "Immagine generata" )
    
    generate_btn.click(
        fn=genera_immagine,
        input=[prompt, negative_prompt, larghezza, altezza, passaggi, cfg, seed],
        output=[immagine_output]
    )
    
    # Aggiungi sezione esempi
    gr.Esempi(
        esempi=ESEMPI,
        input=[prompt, negative_prompt, larghezza, altezza, passaggi, cfg, seed],
        output=[immagine_output],
        fn=genera_immagine,
        esempi_cache= Vero ,
        label= "Esempi di prompt: fai clic per provare!"
    )

se __nome__ == "__principale__" :
    app.launch(share= True )