Fermer

décembre 10, 2025

Génération d’images OpenAI

Génération d’images OpenAI


Découvrez la génération d’images OpenAI et comment générer des images à partir d’invites de texte, personnaliser et affiner les sorties et les afficher dans une interface React.

La génération d’images IA a évolué rapidement, passant d’une nouveauté à un outil que les développeurs et les créateurs utilisent pour prototyper des idées et donner vie à des concepts imaginatifs.

Modèle d’image GPT d’OpenAIcombiné avec le API d’imagesapporte des capacités de génération d’images directement dans nos applications JavaScript/TypeScript. Que nous construisions des systèmes de profils utilisateur, des outils de création de contenu ou des interfaces de prototypage de conception, comprendre comment générer, éditer et affiner des images par programmation peut améliorer notre processus de création et de développement.

Dans cet article, nous explorerons les capacités de génération d’images d’OpenAI à l’aide de TypeScript et de l’API Images. Nous allons parcourir la génération d’images à partir d’invites de texte, la personnalisation des options de sortie, l’affinement itératif des résultats et leur affichage dans une interface React à l’aide des composants Progress KendoReact.

Prérequis : Pour suivre, vous aurez besoin d’une clé API OpenAI, que vous pouvez obtenir auprès de plateforme.openai.com.

Comprendre les capacités de génération d’images d’OpenAI

OpenAI Modèle d’image GPT est conçu pour générer des images de haute qualité à partir de descriptions textuelles. L’API Images fournit une interface simple pour créer des images avec le gpt-image-1 modèle (ainsi que l’ancien DALL-E modèles).

Le processus fonctionne en appelant le /v1/images/generations point final avec nos paramètres rapides et souhaités et le modèle renvoie des données d’image codées en base64 que nous pouvons immédiatement utiliser dans nos applications.

Commencer

Commençons par un simple composant React qui génère une image à partir d’une invite de texte. Nous utiliserons le SDK JavaScript OpenAI et construisez tout en un seul App.tsx déposer.

Tout d’abord, nous allons installer le package OpenAI :

npm install openai

Ensuite, nous créerons notre composant de base de génération d’images :

import React, { useState } from "react";
import OpenAI from "openai";

const App = () => {
  const [imageUrl, setImageUrl] = useState("");
  const [loading, setLoading] = useState(false);

  const generateImage = async () => {
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    const response = await openai.images.generate({
      model: "gpt-image-1",
      prompt: "A serene mountain landscape at sunset",
      n: 1,
      size: "1024x1024",
    });

    const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
    setImageUrl(base64Image);
    setLoading(false);
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>OpenAI Image Generation</h1>
      <button onClick={generateImage} disabled={loading}>
        {loading ? "Generating..." : "Generate Image"}
      </button>
      {imageUrl && (
        <img
          src={imageUrl}
          alt="Generated"
          style={{ maxWidth: "500px", marginTop: "20px" }}
        />
      )}
    </div>
  );
};

export default App;

Dans l’exemple de code ci-dessus, nous appelons openai.images.generate() avec le gpt-image-1 modèle et notre invite. La réponse contient un data tableau avec des images générées, où chaque objet image a un b64_json propriété contenant l’image codée en base64. Nous convertissons cela en une URL de données pour un affichage immédiat dans notre <img> étiqueter.

Note: Paramètre dangerouslyAllowBrowser: true permet à la clé API d’être utilisée côté client. En production, nous devrions effectuer ces appels depuis un serveur backend pour sécuriser votre clé API. De plus, n’intégrez jamais votre clé API directement dans le code et ne l’exposez jamais dans des référentiels publics.

Lorsque nous exécutons l’application et cliquons sur le bouton « Générer une image », le composant fait une requête à l’API d’OpenAI et affiche l’image générée une fois qu’elle est prête :

Construire un générateur d’images dynamiques

Développons notre composant pour permettre aux utilisateurs de saisir des invites personnalisées et de voir les résultats. Pour y parvenir, nous ajouterons la gestion de l’état pour l’invite et mettrons à jour notre interface comme suit :

const App = () => {
  const [prompt, setPrompt] = useState("");
  const [imageUrl, setImageUrl] = useState("");
  const [loading, setLoading] = useState(false);

  const generateImage = async () => {
    if (!prompt) return;
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    const response = await openai.images.generate({
      model: "gpt-image-1",
      prompt: prompt,
      size: "1024x1024",
      quality: "high",
    });

    const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
    setImageUrl(base64Image);
    setLoading(false);
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>OpenAI Image Generation</h1>
      <div style={{ marginBottom: "20px" }}>
        <input
          type="text"
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          placeholder="Describe the image you want to generate..."
          style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
        />
        <button onClick={generateImage} disabled={loading || !prompt}>
          {loading ? "Generating..." : "Generate Image"}
        </button>
      </div>
      {imageUrl && (
        <img
          src={imageUrl}
          alt="Generated"
          style={{ maxWidth: "500px", marginTop: "20px" }}
        />
      )}
    </div>
  );
};

export default App;

Dans l’exemple de code ci-dessus, nous avons ajouté un prompt variable d’état et un champ de saisie qui permet aux utilisateurs de saisir leurs invites personnalisées. Le generateImage La fonction utilise désormais cette valeur d’invite dynamique au lieu d’une chaîne codée en dur, rendant l’interface interactive.

Les utilisateurs peuvent désormais saisir n’importe quelle invite de leur choix et générer des images personnalisées à la demande. Voici un exemple de saisie d’une invite pour « Une oasis du désert avec des palmiers et un ciel bleu clair ».

Raffinement itératif avec l’édition d’images

L’une des fonctionnalités puissantes de la génération d’images d’OpenAI est la possibilité de modifier images existantes. En utilisant le /v1/images/edits point final, nous pouvons affiner les images générées en fonction de nouvelles invites.

Ajoutons des fonctionnalités d’édition d’images à notre composant :

const App = () => {
  const [prompt, setPrompt] = useState("");
  const [imageUrl, setImageUrl] = useState("");
  const [loading, setLoading] = useState(false);
  const [editPrompt, setEditPrompt] = useState("");

  const generateImage = async () => {
    if (!prompt) return;
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    const response = await openai.images.generate({
      model: "gpt-image-1",
      prompt: prompt,
      size: "1024x1024",
      quality: "high",
    });

    const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
    setImageUrl(base64Image);
    setLoading(false);
  };

  const editImage = async () => {
    if (!editPrompt || !imageUrl) return;
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    // Convert base64 to File object
    const base64Data = imageUrl.split(",")[1];
    const byteCharacters = atob(base64Data);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: "image/png" });
    const file = new File([blob], "image.png", { type: "image/png" });

    const response = await openai.images.edit({
      model: "gpt-image-1",
      image: file,
      prompt: editPrompt,
      size: "1024x1024",
    });

    const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
    setImageUrl(base64Image);
    setEditPrompt("");
    setLoading(false);
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>OpenAI Image Generation</h1>

      {/* Initial Generation */}
      <div style={{ marginBottom: "20px" }}>
        <input
          type="text"
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          placeholder="Describe the image you want to generate..."
          style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
        />
        <button onClick={generateImage} disabled={loading || !prompt}>
          {loading ? "Generating..." : "Generate Image"}
        </button>
      </div>

      {/* Current Image */}
      {imageUrl && (
        <div style={{ marginTop: "20px" }}>
          <img src={imageUrl} alt="Generated" style={{ maxWidth: "500px" }} />
        </div>
      )}

      {/* Edit Section */}
      {imageUrl && (
        <div style={{ marginTop: "20px" }}>
          <h3>Edit Image</h3>
          <input
            type="text"
            value={editPrompt}
            onChange={(e) => setEditPrompt(e.target.value)}
            placeholder="e.g., 'Make it more colorful' or 'Add mountains in the background'"
            style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
          />
          <button onClick={editImage} disabled={loading || !editPrompt}>
            {loading ? "Editing..." : "Edit Image"}
          </button>
        </div>
      )}
    </div>
  );
};

export default App;

Ce composant étendu introduit des capacités d’édition d’images. Nous avons ajouté un editImage fonction qui convertit l’image base64 actuelle en un objet File, l’envoie au /v1/images/edits point final avec une nouvelle invite et met à jour l’affichage.

La fonction d’édition d’images nous permet d’affiner de manière itérative nos images générées. Nous pourrions commencer par « un paysage urbain futuriste », puis le modifier avec des invites telles que « ajouter des néons » ou « donner l’impression qu’il pleut ».

Affichage des images générées avec KendoReact

Alors que nous utilisions le HTML standard <img> balises, l’intégration de composants KendoReact peut créer une interface plus raffinée et prête pour la production. Le Composant avatar KendoReact est utile pour afficher les images de profil générées ou les images destinées aux utilisateurs.

Tout d’abord, installez le package de mise en page KendoReact :

npm install @progress/kendo-react-layout

Améliorons l’affichage de l’historique de nos images à l’aide du composant Avatar. Nous envelopperons chaque image générée dans un composant Avatar pour créer une présentation cohérente et soignée.

Voici l’implémentation finale complète où le principal changement que nous avons apporté maintenant est d’afficher l’historique des images générées à l’aide du composant Avatar :

import React, { useState } from "react";
import OpenAI from "openai";
import { Avatar } from "@progress/kendo-react-layout";

const App = () => {
  const [prompt, setPrompt] = useState("");
  const [imageUrl, setImageUrl] = useState("");
  const [imageHistory, setImageHistory] = useState<Array<{ url: string; prompt: string }>>([]);
  const [loading, setLoading] = useState(false);
  const [editPrompt, setEditPrompt] = useState("");

  const generateImage = async () => {
    if (!prompt) return;
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    try {
      const response = await openai.images.generate({
        model: "gpt-image-1",
        prompt: prompt,
        size: "1024x1024",
        quality: "high",
      });

      const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
      setImageUrl(base64Image);
      setImageHistory([{ url: base64Image, prompt }]);
    } catch (error) {
      console.error("Error generating image:", error);
    } finally {
      setLoading(false);
    }
  };

  const editImage = async () => {
    if (!editPrompt || !imageUrl) return;
    setLoading(true);

    const openai = new OpenAI({
      apiKey: "YOUR_OPENAI_API_KEY",
      dangerouslyAllowBrowser: true,
    });

    try {
      // Convert base64 to File object
      const base64Data = imageUrl.split(",")[1];
      const byteCharacters = atob(base64Data);
      const byteNumbers = new Array(byteCharacters.length);
      for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
      }
      const byteArray = new Uint8Array(byteNumbers);
      const blob = new Blob([byteArray], { type: "image/png" });
      const file = new File([blob], "image.png", { type: "image/png" });

      const response = await openai.images.edit({
        model: "gpt-image-1",
        image: file,
        prompt: editPrompt,
        size: "1024x1024",
      });

      const base64Image = `data:image/png;base64,${response.data?.[0].b64_json}`;
      setImageUrl(base64Image);
      setImageHistory([
        ...imageHistory,
        { url: base64Image, prompt: editPrompt },
      ]);
      setEditPrompt("");
    } catch (error) {
      console.error("Error editing image:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>OpenAI Image Generation</h1>

      {/* Initial Generation */}
      <div style={{ marginBottom: "20px" }}>
        <input
          type="text"
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          placeholder="Describe the image you want to generate..."
          style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
        />
        <button onClick={generateImage} disabled={loading || !prompt}>
          {loading ? "Generating..." : "Generate Image"}
        </button>
      </div>

      {/* Current Image */}
      {imageUrl && (
        <div style={{ marginTop: "20px" }}>
          <img src={imageUrl} alt="Generated" style={{ maxWidth: "500px" }} />
        </div>
      )}

      {/* Edit Section */}
      {imageUrl && (
        <div style={{ marginTop: "20px" }}>
          <h3>Edit Image</h3>
          <input
            type="text"
            value={editPrompt}
            onChange={(e) => setEditPrompt(e.target.value)}
            placeholder="e.g., 'Make it more colorful' or 'Add mountains in the background'"
            style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
          />
          <button onClick={editImage} disabled={loading || !editPrompt}>
            {loading ? "Editing..." : "Edit Image"}
          </button>
        </div>
      )}

      {/* Image History with KendoReact Avatar */}
      {imageHistory.length > 0 && (
        <div style={{ marginTop: "30px" }}>
          <h3>Generation History</h3>
          <div style={{ display: "flex", gap: "20px", flexWrap: "wrap" }}>
            {imageHistory.map((img, idx) => (
              <div key={idx} style={{ textAlign: "center" }}>
                <Avatar type="image" size="large" rounded="medium" border={true}>
                  <img src={img.url} alt={`Version ${idx + 1}`} />
                </Avatar>
                <p
                  style={{
                    fontSize: "12px",
                    maxWidth: "150px",
                    marginTop: "8px",
                  }}
                >
                  {img.prompt}
                </p>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default App;

Le composant Avatar fournit une présentation cohérente et stylée pour les images avec une prise en charge intégrée des bordures, des coins arrondis et des différentes tailles. Ceci est particulièrement utile lors de la génération de photos de profil ou lorsque nous avons besoin d’un affichage uniforme pour plusieurs images.

Par exemple, nous pourrions générer une photo de profil initiale avec l’invite « une illustration de photo professionnelle », puis l’affiner de manière itérative avec des modifications telles que « ajouter des lunettes », « rendre l’arrière-plan bleu » et « ajouter un sourire amical », chaque version étant affichée proprement en bas à l’aide du composant Avatar.

Conclure

Les capacités de génération d’images d’OpenAI, optimisées par le modèle GPT Image et l’API Images, amènent la création d’images directement dans nos applications JavaScript. Nous avons exploré comment générer des images à partir d’invites de texte, modifier et affiner les résultats de manière itérative et les afficher dans des interfaces raffinées à l’aide de React et du composant KendoReact Avatar.

Pour approfondir la génération d’images et la bibliothèque KendoReact, consultez les ressources suivantes :




Source link