Cours Vibe coding avec l'IA · Module 10: Clone de TikTok
Génération d'images par IA - DALL-E/Stable Diffusion
Générer des images avec l'IA.
OpenAI DALL-E
1npm install openai1import OpenAI from 'openai';
2
3const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
4
5async function generateImage(prompt: string) {
6 const response = await openai.images.generate({
7 model: "dall-e-3",
8 prompt,
9 n: 1,
10 size: "1024x1024"
11 });
12
13 return response.data[0].url;
14}
15
16function ImageGenerator() {
17 const [prompt, setPrompt] = useState("");
18 const [imageUrl, setImageUrl] = useState("");
19 const [loading, setLoading] = useState(false);
20
21 const handleGenerate = async () => {
22 setLoading(true);
23 const url = await generateImage(prompt);
24 setImageUrl(url);
25 setLoading(false);
26 };
27
28 return (
29 <div>
30 <textarea
31 value={prompt}
32 onChange={(e) => setPrompt(e.target.value)}
33 placeholder="Décris l'image que tu veux générer..."
34 className="w-full border rounded p-3"
35 />
36 <button
37 onClick={handleGenerate}
38 disabled={loading}
39 className="bg-blue-600 text-white px-4 py-2 rounded"
40 >
41 {loading ? 'Génération...' : 'Générer l\'image'}
42 </button>
43 {imageUrl && <img src={imageUrl} alt="Generated" className="mt-4" />}
44 </div>
45 );
46}À bientôt !
Code de cette leçon : App.jsx
1// Enregistreur de vidéo
2import { useState, useEffect } from 'react';
3
4export default function App() {
5 const [isRecording, setIsRecording] = useState(false);
6 const [duration, setDuration] = useState(0);
7 const maxDuration = 60;
8
9 useEffect(() => {
10 let interval;
11 if (isRecording) {
12 interval = setInterval(() => {
13 setDuration(d => {
14 if (d >= maxDuration) {
15 setIsRecording(false);
16 return d;
17 }
18 return d + 0.1;
19 });
20 }, 100);
21 } else {
22 setDuration(0);
23 }
24 return () => clearInterval(interval);
25 }, [isRecording]);
26
27 return (
28 <div className="h-screen bg-black flex flex-col">
29 {/* Aperçu de la vidéo */}
30 <div className="flex-1 relative bg-gradient-to-br from-purple-900 to-blue-900 flex items-center justify-center">
31 <div className="text-9xl">◆</div>
32
33 {/* Indicateur d'enregistrement */}
34 {isRecording && (
35 <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
36 <div className="w-20 h-20 border-4 border-red-500 rounded-full animate-pulse"></div>
37 </div>
38 )}
39
40 {/* Indicateur de son */}
41 <div className="absolute top-4 right-4 bg-black/50 px-3 py-2 rounded-full text-white text-sm flex items-center gap-2">
42 Pirate's Anthem
43 </div>
44 </div>
45
46 {/* Commandes */}
47 <div className="bg-black border-t border-gray-800 p-6">
48 {/* Barre de durée */}
49 <div className="mb-6">
50 <div className="h-1 bg-gray-700 rounded-full overflow-hidden">
51 <div
52 className={`h-full transition-all ${isRecording ? 'bg-red-500' : 'bg-gray-500'}`}
53 style={{ width: `${(duration / maxDuration) * 100}%` }}
54 />
55 </div>
56 <div className="flex justify-between mt-2 text-xs text-gray-400">
57 <span>{duration.toFixed(1)}s</span>
58 <span>{maxDuration}s</span>
59 </div>
60 </div>
61
62 {/* Actions */}
63 <div className="flex items-center justify-around">
64 {/* Effets */}
65 <button className="flex flex-col items-center gap-1">
66 <div className="w-12 h-12 bg-gray-800 rounded-full flex items-center justify-center text-2xl">
67 ◆
68 </div>
69 <span className="text-xs text-white">Effets</span>
70 </button>
71
72 {/* Bouton d'enregistrement */}
73 <button
74 onClick={() => setIsRecording(!isRecording)}
75 className={`w-20 h-20 rounded-full border-4 flex items-center justify-center transition ${
76 isRecording ? 'border-red-500 bg-red-500' : 'border-white bg-transparent'
77 }`}
78 >
79 {isRecording && <div className="w-8 h-8 bg-white rounded"></div>}
80 </button>
81
82 {/* Sons */}
83 <button className="flex flex-col items-center gap-1">
84 <div className="w-12 h-12 bg-gray-800 rounded-full flex items-center justify-center text-2xl">
85 ◉
86 </div>
87 <span className="text-xs text-white">Sons</span>
88 </button>
89 </div>
90 </div>
91 </div>
92 );
93}Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. À quoi sert OpenAI DALL-E selon la leçon ?
2. Quel nom de modèle le code de génération d'image utilise-t-il ?
Tâches pratiques dans le jeu
- Tri horizontal
Ordonne le début de l'appel de génération d'image OpenAI :