Last commit not found
import tkinter as tk | |
from tkinter import ttk, scrolledtext, messagebox | |
from PIL import Image, ImageTk | |
import os | |
from datetime import datetime | |
import json | |
import requests | |
from io import BytesIO | |
import base64 | |
import time | |
class DrawingTutorialApp: | |
def __init__(self, root): | |
self.root = root | |
self.root.title("Générateur de Tutoriel de Dessin") | |
# Configuration de l'API Hugging Face | |
self.API_URL = "https://api-inference.huggingface.co/models/stabilityai/sdxl-turbo" | |
# Remplacez par votre token | |
# Configuration des styles | |
self.setup_styles() | |
# Variables | |
self.current_step = 0 | |
self.generated_images = [] | |
self.steps_description = [] | |
# Création de l'interface | |
self.create_interface() | |
def setup_styles(self): | |
style = ttk.Style() | |
style.configure('TButton', padding=5) | |
style.configure('TFrame', padding=5) | |
def create_interface(self): | |
# Frame principal | |
main_frame = ttk.Frame(self.root) | |
main_frame.pack(expand=True, fill='both', padx=10, pady=10) | |
# Zone de description | |
desc_frame = ttk.LabelFrame(main_frame, text="Description du dessin") | |
desc_frame.pack(fill='x', pady=5) | |
self.description_text = scrolledtext.ScrolledText(desc_frame, height=4) | |
self.description_text.pack(fill='x', padx=5, pady=5) | |
# Boutons de contrôle | |
control_frame = ttk.Frame(main_frame) | |
control_frame.pack(fill='x', pady=5) | |
ttk.Button(control_frame, text="Générer les étapes", | |
command=self.generate_steps).pack(side='left', padx=5) | |
ttk.Button(control_frame, text="Étape précédente", | |
command=self.previous_step).pack(side='left', padx=5) | |
ttk.Button(control_frame, text="Étape suivante", | |
command=self.next_step).pack(side='left', padx=5) | |
# Zone d'affichage | |
self.display_frame = ttk.LabelFrame(main_frame, text="Aperçu de l'étape") | |
self.display_frame.pack(fill='both', expand=True, pady=5) | |
self.image_label = ttk.Label(self.display_frame) | |
self.image_label.pack(padx=5, pady=5) | |
# Zone de description des étapes | |
self.step_description = ttk.Label(self.display_frame, | |
text="Aucune étape générée", | |
wraplength=400) | |
self.step_description.pack(padx=5, pady=5) | |
# Indicateur de progression | |
self.progress_label = ttk.Label(main_frame, text="") | |
self.progress_label.pack(pady=5) | |
def query_image(self, prompt): | |
"""Génère une image via l'API Hugging Face""" | |
try: | |
response = requests.post( | |
self.API_URL, | |
headers=self.headers, | |
json={ | |
"inputs": prompt, | |
"parameters": { | |
"num_inference_steps": 1, | |
"guidance_scale": 0.0, | |
} | |
} | |
) | |
# Vérifier si la requête a réussi | |
if response.status_code != 200: | |
raise Exception(f"Erreur API: {response.status_code}") | |
# Vérifier si le modèle est en cours de chargement | |
if response.status_code == 200 and "error" in response.json(): | |
if "currently loading" in response.json()["error"]: | |
print("Modèle en cours de chargement, attente...") | |
time.sleep(20) # Attendre et réessayer | |
return self.query_image(prompt) | |
# Traiter la réponse | |
image_bytes = response.content | |
image = Image.open(BytesIO(image_bytes)) | |
return image | |
except Exception as e: | |
print(f"Erreur lors de la génération d'image: {e}") | |
messagebox.showerror("Erreur", f"Erreur lors de la génération d'image: {e}") | |
return None | |
def generate_steps(self): | |
description = self.description_text.get("1.0", "end-1c") | |
if not description: | |
messagebox.showwarning("Attention", "Veuillez entrer une description") | |
return | |
# Définition des étapes et prompts associés | |
steps = [ | |
{ | |
"name": "Esquisse de base et formes géométriques", | |
"prompt": f"basic sketch with geometric shapes of {description}, lineart, sketch style, black and white" | |
}, | |
{ | |
"name": "Ajout des détails principaux", | |
"prompt": f"detailed sketch of {description}, more defined lines, black and white drawing" | |
}, | |
{ | |
"name": "Affinement des lignes", | |
"prompt": f"refined line drawing of {description}, clean lines, professional sketch" | |
}, | |
{ | |
"name": "Ajout des ombres de base", | |
"prompt": f"shaded sketch of {description}, basic shadows and values, grayscale" | |
}, | |
{ | |
"name": "Colorisation de base", | |
"prompt": f"basic colored version of {description}, flat colors, simple coloring" | |
}, | |
{ | |
"name": "Ajout des détails de couleur", | |
"prompt": f"detailed colored drawing of {description}, with shading and color details" | |
}, | |
{ | |
"name": "Finalisation et mise en valeur", | |
"prompt": f"final polished illustration of {description}, complete with details and professional finish" | |
} | |
] | |
# Réinitialisation des listes | |
self.generated_images = [] | |
self.steps_description = [] | |
# Génération des images pour chaque étape | |
for i, step in enumerate(steps): | |
self.progress_label.configure( | |
text=f"Génération de l'étape {i+1}/{len(steps)}: {step['name']}") | |
self.root.update() | |
image = self.query_image(step['prompt']) | |
if image: | |
self.generated_images.append(image) | |
self.steps_description.append(f"{step['name']}\n{step['prompt']}") | |
else: | |
messagebox.showerror("Erreur", f"Échec de la génération pour l'étape {i+1}") | |
continue | |
if self.generated_images: | |
self.progress_label.configure(text="Génération terminée!") | |
self.current_step = 0 | |
self.update_display() | |
else: | |
self.progress_label.configure(text="Échec de la génération") | |
def update_display(self): | |
if not self.generated_images: | |
return | |
image = self.generated_images[self.current_step] | |
# Redimensionner l'image si nécessaire | |
image = image.resize((400, 400), Image.Resampling.LANCZOS) | |
photo = ImageTk.PhotoImage(image) | |
self.image_label.configure(image=photo) | |
self.image_label.image = photo | |
step_text = f"Étape {self.current_step + 1}/{len(self.generated_images)}\n" | |
step_text += self.steps_description[self.current_step] | |
self.step_description.configure(text=step_text) | |
def previous_step(self): | |
if self.current_step > 0: | |
self.current_step -= 1 | |
self.update_display() | |
def next_step(self): | |
if self.current_step < len(self.generated_images) - 1: | |
self.current_step += 1 | |
self.update_display() | |
def main(): | |
root = tk.Tk() | |
app = DrawingTutorialApp(root) | |
root.mainloop() | |
if __name__ == "__main__": | |
main() |