File size: 9,771 Bytes
4225fe9
ebb5440
7a0fe93
ebb5440
 
2e33d63
 
8c7203f
6c1eb66
2e33d63
 
 
 
 
 
eddc67d
6c1eb66
 
 
 
 
 
2e33d63
ebb5440
2e33d63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d1ec474
6c1eb66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e33d63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ac0e5d3
2e33d63
 
 
 
 
6c1eb66
 
 
 
2e33d63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c1eb66
2e33d63
 
 
 
 
 
 
 
 
6c1eb66
 
2e33d63
6c1eb66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e33d63
6c1eb66
 
 
2e33d63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c1eb66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e33d63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d1ec474
2e33d63
 
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
import streamlit as st
from PIL import Image
import torch
import tempfile
import os
import io
import base64

# Configuration de la page - IMPORTANT pour Hugging Face Spaces
st.set_page_config(
    page_title="Video AI Generator",
    page_icon="🎥",
    layout="wide",
    initial_sidebar_state="expanded"
)

# Configuration spéciale pour Hugging Face Spaces
if 'HF_SPACE' in os.environ:
    # Désactiver les vérifications CSRF pour HF Spaces
    st.set_option('server.enableCORS', True)
    st.set_option('server.enableXsrfProtection', False)

# Configuration pour éviter les erreurs de mémoire
@st.cache_resource
def load_pipeline():
    """Charge le pipeline avec optimisations mémoire"""
    try:
        from diffusers import StableDiffusionImg2ImgPipeline
        
        # Utiliser un modèle plus léger ou optimisé
        model_id = "runwayml/stable-diffusion-v1-5"
        
        pipeline = StableDiffusionImg2ImgPipeline.from_pretrained(
            model_id,
            torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
            use_safetensors=True,
        )
        
        # Optimisations mémoire
        if torch.cuda.is_available():
            pipeline = pipeline.to("cuda")
            pipeline.enable_memory_efficient_attention()
            pipeline.enable_attention_slicing()
        else:
            pipeline = pipeline.to("cpu")
            
        return pipeline
    except Exception as e:
        st.error(f"Erreur lors du chargement du modèle : {e}")
        return None

def safe_file_upload():
    """Upload de fichier sécurisé avec gestion d'erreurs"""
    try:
        # Upload avec paramètres optimisés pour HF Spaces
        uploaded_file = st.file_uploader(
            "Choisissez une image",
            type=['png', 'jpg', 'jpeg'],
            accept_multiple_files=False,
            key="image_uploader",
            help="Formats supportés: PNG, JPG, JPEG (max 10MB recommandé)"
        )
        
        if uploaded_file is not None:
            # Vérifier la taille du fichier
            file_size = len(uploaded_file.getvalue())
            if file_size > 10 * 1024 * 1024:  # 10MB
                st.warning(f"⚠️ Fichier volumineux ({file_size/1024/1024:.1f}MB). Réduisez la taille pour de meilleures performances.")
            
            # Charger l'image avec gestion d'erreur
            try:
                image = Image.open(uploaded_file)
                st.success(f"✅ Image chargée: {image.size[0]}x{image.size[1]} pixels")
                return image, uploaded_file
            except Exception as img_error:
                st.error(f"❌ Erreur lors du chargement de l'image: {img_error}")
                return None, None
                
    except Exception as upload_error:
        st.error(f"❌ Erreur d'upload: {upload_error}")
        st.info("💡 Essayez de rafraîchir la page ou utilisez un fichier plus petit")
        return None, None
    
    return None, None

def process_image(image, prompt, strength=0.75, guidance_scale=7.5):
    """Traite l'image avec le pipeline"""
    try:
        pipeline = load_pipeline()
        if pipeline is None:
            return None
            
        # Redimensionner l'image pour éviter les problèmes de mémoire
        max_size = 512
        if image.width > max_size or image.height > max_size:
            image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
        
        # S'assurer que l'image est en RGB
        if image.mode != "RGB":
            image = image.convert("RGB")
        
        # Générer l'image
        with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
            result = pipeline(
                prompt=prompt,
                image=image,
                strength=strength,
                guidance_scale=guidance_scale,
                num_inference_steps=20,  # Réduire pour plus de vitesse
                height=image.height,
                width=image.width
            )
        
        return result.images[0]
    except Exception as e:
        st.error(f"Erreur lors de la génération : {e}")
        return None

# Interface utilisateur
def main():
    st.title("🎥 Générateur Video AI")
    st.markdown("Transformez vos images avec l'IA")
    
    # Afficher le statut de l'environnement
    if 'HF_SPACE' in os.environ:
        st.info("🚀 Application déployée sur Hugging Face Spaces")
    
    # Sidebar pour les paramètres
    with st.sidebar:
        st.header("⚙️ Paramètres")
        
        strength = st.slider(
            "Force de transformation",
            min_value=0.1,
            max_value=1.0,
            value=0.75,
            step=0.05,
            help="Plus élevé = plus de changements"
        )
        
        guidance_scale = st.slider(
            "Échelle de guidance",
            min_value=1.0,
            max_value=20.0,
            value=7.5,
            step=0.5,
            help="Plus élevé = plus fidèle au prompt"
        )
        
        st.markdown("---")
        st.markdown("💡 **Conseils:**")
        st.markdown("- Utilisez des images < 10MB")
        st.markdown("- Format recommandé: PNG, JPG")
        st.markdown("- Résolution max: 512x512")
    
    # Section principale
    col1, col2 = st.columns([1, 1])
    
    with col1:
        st.header("📤 Image d'entrée")
        
        # Upload de fichier sécurisé
        input_image, uploaded_file = safe_file_upload()
        
        if input_image is not None:
            # Redimensionner pour l'affichage
            display_image = input_image.copy()
            if display_image.width > 400:
                display_image.thumbnail((400, 400), Image.Resampling.LANCZOS)
            
            st.image(display_image, caption="Image d'origine", use_column_width=True)
            
            # Zone de texte pour le prompt
            prompt = st.text_area(
                "🎨 Décrivez la transformation souhaitée:",
                placeholder="Ex: transformer en anime style, ajouter des couleurs vives, style cyberpunk...",
                height=100,
                key="prompt_input"
            )
            
            # Bouton de génération
            if st.button("🚀 Générer", type="primary", use_container_width=True):
                if prompt.strip():
                    with st.spinner("Génération en cours... Cela peut prendre quelques minutes."):
                        result_image = process_image(
                            input_image, 
                            prompt, 
                            strength, 
                            guidance_scale
                        )
                    
                    if result_image:
                        # Stocker le résultat dans la session
                        st.session_state['result_image'] = result_image
                        st.success("✅ Génération terminée!")
                        st.rerun()
                    else:
                        st.error("❌ Erreur lors de la génération")
                else:
                    st.warning("⚠️ Veuillez entrer une description")
    
    with col2:
        st.header("🎨 Résultat")
        
        # Afficher le résultat s'il existe
        if 'result_image' in st.session_state:
            result_image = st.session_state['result_image']
            
            # Redimensionner pour l'affichage
            display_result = result_image.copy()
            if display_result.width > 400:
                display_result.thumbnail((400, 400), Image.Resampling.LANCZOS)
            
            st.image(display_result, caption="Image transformée", use_column_width=True)
            
            # Bouton de téléchargement
            try:
                buffered = io.BytesIO()
                result_image.save(buffered, format="PNG")
                
                st.download_button(
                    label="💾 Télécharger le résultat",
                    data=buffered.getvalue(),
                    file_name="result_ai.png",
                    mime="image/png",
                    use_container_width=True
                )
            except Exception as e:
                st.error(f"Erreur lors de la préparation du téléchargement: {e}")
        else:
            st.info("👈 Uploadez une image et entrez un prompt pour commencer")
    
    # Section de dépannage
    with st.expander("🔧 Problèmes d'upload?"):
        st.markdown("""
        **Si vous ne pouvez pas charger d'images:**
        
        1. **Rafraîchissez** la page (F5)
        2. **Réduisez** la taille de votre image (< 5MB)
        3. **Changez** le format (essayez JPG au lieu de PNG)
        4. **Utilisez** un autre navigateur
        5. **Attendez** quelques secondes et réessayez
        
        **Formats supportés:** PNG, JPG, JPEG
        **Taille recommandée:** < 10MB
        """)
    
    # Instructions
    with st.expander("📖 Instructions d'utilisation"):
        st.markdown("""
        ### Comment utiliser cette application:
        
        1. **Uploadez une image** dans la section de gauche
        2. **Décrivez la transformation** que vous souhaitez
        3. **Ajustez les paramètres** dans la sidebar si nécessaire
        4. **Cliquez sur Générer** et patientez
        5. **Téléchargez le résultat** une fois terminé
        
        ### Exemples de prompts:
        - "transformer en style anime"
        - "ajouter des couleurs arc-en-ciel"
        - "style cyberpunk néon"
        - "portrait artistique à l'aquarelle"
        - "paysage fantastique avec des dragons"
        """)

if __name__ == "__main__":
    main()