Intégration de l'API DALL-E 2 dans une application PureBasic

Programmation d'applications complexes
seblamb
Messages : 1
Inscription : dim. 08/déc./2024 19:15

Intégration de l'API DALL-E 2 dans une application PureBasic

Message par seblamb »

Bonjour à tous,

Je développe une application de traitement d'images en PureBasic et j'aimerais intégrer l'API DALL-E 2 pour générer des images. Voici mes objectifs :

Créer une interface utilisateur pour les prompts
Gérer les appels API vers DALL-E 2
Sauvegarder les images générées

Avez-vous des retours d'expérience sur :

Les requêtes HTTP vers l'API OpenAI en PureBasic ?
Le traitement du JSON dans les réponses ?
La gestion des erreurs et des timeouts ?

Merci pour votre aide !
Dernière modification par seblamb le lun. 13/janv./2025 16:17, modifié 1 fois.
Avatar de l’utilisateur
falsam
Messages : 7362
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Intégration de l'API DALL-E 2 dans une application PureBasic

Message par falsam »

Bonjour et bienvenue (J'espère que tu n'es pas un bot)
seblamb a écrit : mer. 11/déc./2024 8:50 Créer une interface utilisateur pour les prompts
Gérer les appels API vers DALL-E 2
Sauvegarder les images générées

Avez-vous des retours d'expérience sur :

Les requêtes HTTP vers l'API OpenAI en PureBasic ?
Ce lien pourrait t'aider https://www.purebasic.fr/english/viewto ... 52#p610952
seblamb a écrit : mer. 11/déc./2024 8:50 Le traitement du JSON dans les réponses ?
Accessible avec la touche F1 de l'IDE https://www.purebasic.com/french/docume ... index.html
seblamb a écrit : mer. 11/déc./2024 8:50 La gestion des erreurs et des timeouts ?
https://www.purebasic.com/french/docume ... index.html
Configuration : Windows 11 Famille 64-bit - PB 6.23 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
MarkUS
Messages : 1
Inscription : jeu. 27/févr./2025 20:02

Re: Intégration de l'API DALL-E 2 dans une application PureBasic

Message par MarkUS »

Bonjour,

Pour les requêtes HTTP en PureBasic, tu peux utiliser ReceiveHTTPMemory() pour interagir avec l'API OpenAI. Pour traiter le JSON, la bibliothèque ParseJSON() te sera utile pour extraire les données des réponses. Pense aussi à gérer les erreurs avec des vérifications sur les codes de retour HTTP et à intégrer un timeout pour éviter que l’appli ne bloque en cas de souci.

Hâte de voir ton application en action ! 😊
Avatar de l’utilisateur
Ar-S
Messages : 9556
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Intégration de l'API DALL-E 2 dans une application PureBasic

Message par Ar-S »

Salut, essaye ça,
Vu que j'ai pas d'API DALL-E ça me retourne bien un message d'erreur de la requête mais pour le reste vois par toi même du coup.

Code : Tout sélectionner


Global ldvm, Prompt$, APIKey$, ImageUrl$, FileName$
Global imageRendu, Button_Generate, Button_Save
Global ComboBox_Size, String_Prompt, String_APIKey, Spin_NumImages

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()



Procedure SendDalleRequest()
  Define.s jsonRequest, jsonResponse, url
  Define.i httpRequest
  Define *response
  NewMap Header$()
  
  Prompt$ = GetGadgetText(String_Prompt)
  APIKey$ = GetGadgetText(String_APIKey)
  Define numImages = GetGadgetState(Spin_NumImages)
  Define.s size = GetGadgetText(ComboBox_Size)
  
  If Prompt$ = "" Or APIKey$ = ""
    MessageRequester("Erreur", "Veuillez remplir tous les champs.")
    ProcedureReturn
  EndIf
  
  jsonRequest = "{" + Chr(34) + "prompt" + Chr(34) + ": " + Chr(34) + Prompt$ + Chr(34) + ", "
  jsonRequest + Chr(34) + "n" + Chr(34) + ": " + Str(numImages) + ", "
  jsonRequest + Chr(34) + "size" + Chr(34) + ": " + Chr(34) + size + Chr(34) + "}"
  
  url = "https://api.openai.com/v1/images/generations"
  Header$("Content-Type") = "application/json"
  Header$("Authorization") = "Bearer " + APIKey$
  
  httpRequest = HTTPRequest(#PB_HTTP_Post, url, jsonRequest, 0, Header$())
  
  If httpRequest
    *response = HTTPMemory(httpRequest)
    jsonResponse = PeekS(*response, MemorySize(*response), #PB_UTF8)
    FinishHTTP(httpRequest)
    
    If FindString(jsonResponse, "url", 1)
      ImageUrl$ = StringField(jsonResponse, 2, Chr(34) + "url" + Chr(34) + ": " + Chr(34))
      ImageUrl$ = StringField(ImageUrl$, 1, Chr(34))
      
      httpRequest = HTTPRequest(#PB_HTTP_Get, ImageUrl$)
      If httpRequest
        *response = HTTPMemory(httpRequest)
        If *response
          CatchImage(0, *response, MemorySize(*response))
          SetGadgetState(imageRendu, ImageID(0))
          FreeMemory(*response)
        EndIf
        FinishHTTP(httpRequest)
      EndIf
    Else
      MessageRequester("Erreur", "Réponse invalide : " + jsonResponse)
    EndIf
  Else
    MessageRequester("Erreur", "Échec de la requête HTTP.")
  EndIf
EndProcedure

Procedure SaveMyImage()
  If ImageUrl$ = ""
    MessageRequester("Erreur", "Aucune image à enregistrer.")
    ProcedureReturn
  EndIf
  
  FileName$ = SaveFileRequester("Enregistrer l'image sous...", "", "PNG (*.png)|*.png|JPEG (*.jpg)|*.jpg", 0)
  If FileName$ <> ""
    httpRequest = HTTPRequestMemory(#PB_HTTP_Get, ImageUrl$)
    If httpRequest
      If Right(FileName$, 3) = "png"
        SaveImage(0, FileName$, #PB_ImagePlugin_PNG)
      Else
        SaveImage(0, FileName$, #PB_ImagePlugin_JPEG, 8)
      EndIf
      FreeMemory(*response)
    EndIf
    FinishHTTP(httpRequest)
    MessageRequester("Succès", "Image enregistrée avec succès !")
  EndIf
EndProcedure

Procedure OpenWin()
  ldvm = OpenWindow(#PB_Any, 100, 100, 500, 400, "DALL-E Image Generator")
  String_Prompt = StringGadget(#PB_Any, 10, 10, 480, 30, "")
  ComboBox_Size = ComboBoxGadget(#PB_Any, 10, 50, 200, 25)
  AddGadgetItem(ComboBox_Size, -1, "1024x1024")
  AddGadgetItem(ComboBox_Size, -1, "1792x1024")
  AddGadgetItem(ComboBox_Size, -1, "1024x1792")
  SetGadgetState(ComboBox_Size, 0)
  
  Spin_NumImages = SpinGadget(#PB_Any, 220, 50, 50, 25, 1, 4, #PB_Spin_Numeric)
  String_APIKey = StringGadget(#PB_Any, 10, 90, 480, 30, "", #PB_String_Password)
  
  Button_Generate = ButtonGadget(#PB_Any, 10, 130, 100, 30, "Générer")
  Button_Save = ButtonGadget(#PB_Any, 120, 130, 100, 30, "Enregistrer")
  
  imageRendu = ImageGadget(#PB_Any, 10, 170, 480, 220, 0)
  
  BindGadgetEvent(Button_Generate, @SendDalleRequest())
  BindGadgetEvent(Button_Save, @SaveMyImage())
EndProcedure

OpenWin()

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
AntoineB
Messages : 3
Inscription : dim. 13/avr./2025 23:21

Re: Intégration de l'API DALL-E 2 dans une application PureBasic

Message par AntoineB »

Bonjour à tous,

Merci pour toutes ces infos, c’est super intéressant de voir ce que vous arrivez à faire avec l’API DALL·E dans PureBasic.

Personnellement, je trouve DALL·E chouette, mais j’avoue avoir une préférence pour les rendus de Midjourney, que je trouve souvent plus artistiques. Est-ce que quelqu’un sait s’il existe une API officielle pour Midjourney, ou au moins un service tiers qui permettrait de l’intégrer dans une appli ? Je n’ai trouvé que des bots Discord pour l’instant.

Merci d’avance si certains ont exploré cette piste !

Antoine
Avatar de l’utilisateur
MetalOS
Messages : 1541
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Re: Intégration de l'API DALL-E 2 dans une application PureBasic

Message par MetalOS »

Voici un petit utilitaire si vous possédez une clé api OpenAI

Code : Tout sélectionner

; ============================================
; Générateur d'images DALL-E en PureBasic
; By MetalOS
; ============================================

EnableExplicit

; Variables globales
Global Window_Main, 
       Text_Prompt, String_Prompt,
       Button_Generate, Button_Save,
       Image_Display, Image_Canvas,
       Text_Status,
       Text_ApiKey, String_ApiKey,
       Combo_Size, Combo_Quality,
       *ImageBuffer, ImageSize.i,
       CurrentImagePath.s

; Structures
Structure APIResponse
  url.s
  revised_prompt.s
EndStructure

; ============================================
; Procédure pour effectuer la requète API DALL-E
; ============================================
Procedure.s GenerateImage(prompt.s, apiKey.s, size.s = "1024x1024", quality.s = "standard")
  Protected result.s, json.s, tempFile.s
  Protected *buffer, bufferSize.i
  
  ; Échapper les guillemets dans le prompt
  prompt = ReplaceString(prompt, #DQUOTE$, "\" + #DQUOTE$)
  
  ; Construire le JSON pour la requête
  json = "{" + #CRLF$
  json + "  " + #DQUOTE$ + "model" + #DQUOTE$ + ": " + #DQUOTE$ + "dall-e-3" + #DQUOTE$ + "," + #CRLF$
  json + "  " + #DQUOTE$ + "prompt" + #DQUOTE$ + ": " + #DQUOTE$ + prompt + #DQUOTE$ + "," + #CRLF$
  json + "  " + #DQUOTE$ + "n" + #DQUOTE$ + ": 1," + #CRLF$
  json + "  " + #DQUOTE$ + "size" + #DQUOTE$ + ": " + #DQUOTE$ + size + #DQUOTE$ + "," + #CRLF$
  json + "  " + #DQUOTE$ + "quality" + #DQUOTE$ + ": " + #DQUOTE$ + quality + #DQUOTE$ + #CRLF$
  json + "}"
  
  ; Sauvegarder le JSON dans un fichier temporaire
  tempFile = GetTemporaryDirectory() + "dalle_request.json"
  If CreateFile(0, tempFile)
    WriteString(0, json)
    CloseFile(0)
  Else
    ProcedureReturn ""
  EndIf
  
  ; Exécuter curl pour appeler l'API
  Protected curlCmd.s, outputFile.s
  outputFile = GetTemporaryDirectory() + "dalle_response.json"
  
  curlCmd = "curl -s -X POST https://api.openai.com/v1/images/generations "
  curlCmd + "-H " + #DQUOTE$ + "Content-Type: application/json" + #DQUOTE$ + " "
  curlCmd + "-H " + #DQUOTE$ + "Authorization: Bearer " + apiKey + #DQUOTE$ + " "
  curlCmd + "-d @" + #DQUOTE$ + tempFile + #DQUOTE$ + " "
  curlCmd + "-o " + #DQUOTE$ + outputFile + #DQUOTE$
  
  RunProgram("curl", curlCmd, "", #PB_Program_Wait | #PB_Program_Hide)
  
  ; Lire la réponse
  If ReadFile(0, outputFile)
    result = ReadString(0, #PB_File_IgnoreEOL)
    CloseFile(0)
  EndIf
  
  ; Nettoyer les fichiers temporaires
  DeleteFile(tempFile)
  
  ProcedureReturn result
EndProcedure

; ============================================
; Procédure pour extraire l'URL de l'image du JSON
; ============================================
Procedure.s ExtractImageURL(jsonResponse.s)
  Protected pos.i, urlStart.i, urlEnd.i, url.s
  
  ; Chercher "url": "..."
  pos = FindString(jsonResponse, #DQUOTE$ + "url" + #DQUOTE$ + ":")
  If pos > 0
    urlStart = FindString(jsonResponse, #DQUOTE$, pos + 6)
    If urlStart > 0
      urlEnd = FindString(jsonResponse, #DQUOTE$, urlStart + 1)
      If urlEnd > 0
        url = Mid(jsonResponse, urlStart + 1, urlEnd - urlStart - 1)
        ProcedureReturn url
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn ""
EndProcedure

; ============================================
; Procédure pour télécharger l'image
; ============================================
Procedure.s DownloadImage(url.s)
  Protected outputFile.s, curlCmd.s
  
  outputFile = GetTemporaryDirectory() + "dalle_image_" + Str(Date()) + ".png"
  
  curlCmd = "-s -o " + #DQUOTE$ + outputFile + #DQUOTE$ + " " + #DQUOTE$ + url + #DQUOTE$
  
  RunProgram("curl", curlCmd, "", #PB_Program_Wait | #PB_Program_Hide)
  
  If FileSize(outputFile) > 0
    ProcedureReturn outputFile
  Else
    ProcedureReturn ""
  EndIf
EndProcedure

; ============================================
; Procédure pour afficher l'image
; ============================================
Procedure DisplayImage(imagePath.s)
  Protected imageID.i, originalWidth.i, originalHeight.i
  Protected canvasWidth.i, canvasHeight.i, ratio.d
  Protected newWidth.i, newHeight.i, x.i, y.i
  
  ; Charger l'image
  imageID = LoadImage(#PB_Any, imagePath)
  If imageID
    originalWidth = ImageWidth(imageID)
    originalHeight = ImageHeight(imageID)
    
    ; Obtenir les dimensions du canvas
    canvasWidth = GadgetWidth(Image_Canvas)
    canvasHeight = GadgetHeight(Image_Canvas)
    
    ; Calculer le ratio pour ajuster l'image
    Protected ratioW.d, ratioH.d
    ratioW = canvasWidth / originalWidth
    ratioH = canvasHeight / originalHeight
    
    If ratioW < ratioH
      ratio = ratioW
    Else
      ratio = ratioH
    EndIf
    
    newWidth = originalWidth * ratio
    newHeight = originalHeight * ratio
    
    ; Centrer l'image
    x = (canvasWidth - newWidth) / 2
    y = (canvasHeight - newHeight) / 2
    
    ; Dessiner l'image
    If StartDrawing(CanvasOutput(Image_Canvas))
      DrawingMode(#PB_2DDrawing_Default)
      Box(0, 0, canvasWidth, canvasHeight, RGB(240, 240, 240))
      DrawImage(imageID, x, y, newWidth, newHeight)
      StopDrawing()
    EndIf
    
    FreeImage(imageID)
  EndIf
EndProcedure

; ============================================
; Evénements des gadgets
; ============================================
Procedure HandleEvents()
  Protected event.i, prompt.s, apiKey.s, size.s, quality.s
  Protected response.s, imageURL.s, imagePath.s
  
  event = EventGadget()
  
  Select event
    Case Button_Generate
      ; Récupérer les valeurs
      prompt = GetGadgetText(String_Prompt)
      apiKey = GetGadgetText(String_ApiKey)
      
      If Trim(prompt) = ""
        MessageRequester("Erreur", "Veuillez entrer une description pour l'image.", #PB_MessageRequester_Error)
        ProcedureReturn
      EndIf
      
      If Trim(apiKey) = ""
        MessageRequester("Erreur", "Veuillez entrer votre clè API OpenAI.", #PB_MessageRequester_Error)
        ProcedureReturn
      EndIf
      
      ; Obtenir taille et qualité
      Select GetGadgetState(Combo_Size)
        Case 0: size = "1024x1024"
        Case 1: size = "1024x1792"
        Case 2: size = "1792x1024"
      EndSelect
      
      Select GetGadgetState(Combo_Quality)
        Case 0: quality = "standard"
        Case 1: quality = "hd"
      EndSelect
      
      ; Mettre à jour le statut
      SetGadgetText(Text_Status, "Génération en cours...")
      DisableGadget(Button_Generate, #True)
      
      ; Générer l'image
      response = GenerateImage(prompt, apiKey, size, quality)
      
      If response <> ""
        imageURL = ExtractImageURL(response)
        
        If imageURL <> ""
          SetGadgetText(Text_Status, "Téléchargement de l'image...")
          imagePath = DownloadImage(imageURL)
          
          If imagePath <> ""
            CurrentImagePath = imagePath
            DisplayImage(imagePath)
            SetGadgetText(Text_Status, "Image générée avec succès!")
            DisableGadget(Button_Save, #False)
          Else
            SetGadgetText(Text_Status, "Erreur lors du téléchargement de l'image.")
            MessageRequester("Erreur", "Impossible de télécharger l'image.", #PB_MessageRequester_Error)
          EndIf
        Else
          SetGadgetText(Text_Status, "Erreur: impossible d'extraire l'URL de l'image.")
          MessageRequester("Erreur", "Réponse API invalide: " + Left(response, 200), #PB_MessageRequester_Error)
        EndIf
      Else
        SetGadgetText(Text_Status, "Erreur lors de la génération.")
        MessageRequester("Erreur", "Impossible de contacter l'API OpenAI. Vérifiez votre clé API.", #PB_MessageRequester_Error)
      EndIf
      
      DisableGadget(Button_Generate, #False)
      
    Case Button_Save
      If CurrentImagePath <> ""
        Protected savePath.s
        savePath = SaveFileRequester("Sauvegarder l'image", "dalle_image.png", "Images PNG (*.png)|*.png", 0)
        If savePath <> ""
          If Not FindString(savePath, ".png", 0, #PB_String_NoCase)
            savePath + ".png"
          EndIf
          CopyFile(CurrentImagePath, savePath)
          MessageRequester("Succès", "Image sauvegardée avec succès!", #PB_MessageRequester_Info)
        EndIf
      EndIf
      
  EndSelect
EndProcedure

; ============================================
; Création de l'interface
; ============================================
Procedure CreateInterface()
  Protected x.i = 10, y.i = 10
  
  Window_Main = OpenWindow(#PB_Any, 0, 0, 900, 700, "Générateur d'images DALL-E", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  If Window_Main
    ; Clé API
    TextGadget(#PB_Any, x, y, 150, 20, "Clé API OpenAI:")
    String_ApiKey = StringGadget(#PB_Any, x + 150, y, 720, 25, "", #PB_String_Password)
    y + 35
    
    ; Description
    TextGadget(Text_Prompt, x, y, 150, 20, "Description de l'image:")
    y + 25
    String_Prompt = EditorGadget(#PB_Any, x, y, 870, 80)
    SetGadgetText(String_Prompt, "Un chat astronaute flottant dans l'espace avec la Terre en arrière-plan")
    y + 90
    
    ; Options
    TextGadget(#PB_Any, x, y, 100, 20, "Taille:")
    Combo_Size = ComboBoxGadget(#PB_Any, x + 100, y, 150, 25)
    AddGadgetItem(Combo_Size, -1, "1024x1024 (carré)")
    AddGadgetItem(Combo_Size, -1, "1024x1792 (portrait)")
    AddGadgetItem(Combo_Size, -1, "1792x1024 (paysage)")
    SetGadgetState(Combo_Size, 0)
    
    TextGadget(#PB_Any, x + 280, y, 100, 20, "Qualité:")
    Combo_Quality = ComboBoxGadget(#PB_Any, x + 380, y, 150, 25)
    AddGadgetItem(Combo_Quality, -1, "Standard")
    AddGadgetItem(Combo_Quality, -1, "HD")
    SetGadgetState(Combo_Quality, 0)
    
    Button_Generate = ButtonGadget(#PB_Any, x + 560, y, 150, 30, "Générer l'image")
    Button_Save = ButtonGadget(#PB_Any, x + 720, y, 150, 30, "Sauvegarder")
    DisableGadget(Button_Save, #True)
    
    y + 40
    
    ; Zone d'affichage de l'image
    Image_Canvas = CanvasGadget(#PB_Any, x, y, 870, 450)
    If StartDrawing(CanvasOutput(Image_Canvas))
      DrawingMode(#PB_2DDrawing_Default)
      Box(0, 0, 870, 450, RGB(240, 240, 240))
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(350, 220, "L'image apparaîtra ici", RGB(100, 100, 100))
      StopDrawing()
    EndIf
    
    y + 460
    
    ; Statut
    Text_Status = TextGadget(#PB_Any, x, y, 870, 20, "Prèt à générer une image...")
    
  EndIf
EndProcedure

; ============================================
; Programme principal
; ============================================
CreateInterface()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Gadget
      HandleEvents()
      
  EndSelect
ForEver

End
Répondre