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