From f7e982fb20285afac1fbb483c2e0dcb73888fdf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Wed, 23 Apr 2025 15:25:16 -0500 Subject: [PATCH 1/7] feat: add gpt-image-1 support --- image.go | 75 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/image.go b/image.go index 577d7db95..4eb6e13de 100644 --- a/image.go +++ b/image.go @@ -13,51 +13,101 @@ const ( CreateImageSize256x256 = "256x256" CreateImageSize512x512 = "512x512" CreateImageSize1024x1024 = "1024x1024" + // dall-e-3 supported only. CreateImageSize1792x1024 = "1792x1024" CreateImageSize1024x1792 = "1024x1792" + + // gpt-image-1 supported only. + CreateImageSize1536x1024 = "1536x1024" // Landscape + CreateImageSize1024x1536 = "1024x1536" // Portrait ) const ( - CreateImageResponseFormatURL = "url" + // dall-e-2 and dall-e-3 only. CreateImageResponseFormatB64JSON = "b64_json" + CreateImageResponseFormatURL = "url" ) const ( - CreateImageModelDallE2 = "dall-e-2" - CreateImageModelDallE3 = "dall-e-3" + CreateImageModelDallE2 = "dall-e-2" + CreateImageModelDallE3 = "dall-e-3" + CreateImageModelGptImage1 = "gpt-image-1" ) const ( CreateImageQualityHD = "hd" CreateImageQualityStandard = "standard" + + // gpt-image-1 only + CreateImageQualityHigh = "high" + CreateImageQualityMedium = "medium" + CreateImageQualityLow = "low" ) const ( + // dall-e-3 only CreateImageStyleVivid = "vivid" CreateImageStyleNatural = "natural" ) +const ( + // gpt-image-1 only + CreateImageBackgroundTransparent = "transparent" + CreateImageBackgroundOpaque = "opaque" +) + +const ( + // gpt-image-1 only + CreateImageModerationLow = "low" +) + +const ( + // gpt-image-1 only + CreateImageOutputFormatPNG = "png" + CreateImageOutputFormatJPEG = "jpeg" + CreateImageOutputFormatWEBP = "webp" +) + // ImageRequest represents the request structure for the image API. type ImageRequest struct { - Prompt string `json:"prompt,omitempty"` - Model string `json:"model,omitempty"` - N int `json:"n,omitempty"` - Quality string `json:"quality,omitempty"` - Size string `json:"size,omitempty"` - Style string `json:"style,omitempty"` - ResponseFormat string `json:"response_format,omitempty"` - User string `json:"user,omitempty"` + Prompt string `json:"prompt,omitempty"` + Model string `json:"model,omitempty"` + N int `json:"n,omitempty"` + Quality string `json:"quality,omitempty"` + Size string `json:"size,omitempty"` + Style string `json:"style,omitempty"` + ResponseFormat string `json:"response_format,omitempty"` + User string `json:"user,omitempty"` + Background string `json:"background,omitempty"` + Moderation string `json:"moderation,omitempty"` + OutputCompression int `json:"output_compression,omitempty"` + OutputFormat string `json:"output_format,omitempty"` } // ImageResponse represents a response structure for image API. type ImageResponse struct { Created int64 `json:"created,omitempty"` Data []ImageResponseDataInner `json:"data,omitempty"` + Usage ImageResponseUsage `json:"usage,omitempty"` httpHeader } +// ImageResponseInputTokensDetails represents the token breakdown for input tokens. +type ImageResponseInputTokensDetails struct { + TextTokens int `json:"text_tokens,omitempty"` + ImageTokens int `json:"image_tokens,omitempty"` +} + +// ImageResponseUsage represents the token usage information for image API. +type ImageResponseUsage struct { + TotalTokens int `json:"total_tokens,omitempty"` + InputTokens int `json:"input_tokens,omitempty"` + OutputTokens int `json:"output_tokens,omitempty"` + InputTokensDetails ImageResponseInputTokensDetails `json:"input_tokens_details,omitempty"` +} + // ImageResponseDataInner represents a response data structure for image API. type ImageResponseDataInner struct { URL string `json:"url,omitempty"` @@ -91,6 +141,8 @@ type ImageEditRequest struct { N int `json:"n,omitempty"` Size string `json:"size,omitempty"` ResponseFormat string `json:"response_format,omitempty"` + Quality string `json:"quality,omitempty"` + User string `json:"user,omitempty"` } // CreateEditImage - API call to create an image. This is the main endpoint of the DALL-E API. @@ -159,6 +211,7 @@ type ImageVariRequest struct { N int `json:"n,omitempty"` Size string `json:"size,omitempty"` ResponseFormat string `json:"response_format,omitempty"` + User string `json:"user,omitempty"` } // CreateVariImage - API call to create an image variation. This is the main endpoint of the DALL-E API. From d46e0b224f96e87d4c3a11af9715cfe70a65a39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Wed, 23 Apr 2025 15:25:53 -0500 Subject: [PATCH 2/7] feat: add example to generate image using gpt-image-1 model --- examples/images/main.go | 59 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/examples/images/main.go b/examples/images/main.go index 5ee649d22..aeec9056d 100644 --- a/examples/images/main.go +++ b/examples/images/main.go @@ -2,27 +2,74 @@ package main import ( "context" + "encoding/base64" "fmt" "os" + "path/filepath" "github.com/sashabaranov/go-openai" ) +// saveImageToFile saves image data to a file in the specified directory +// Returns the full path where the image was saved or an error +func saveImageToFile(imageData []byte, outputDir, filename string) (string, error) { + // Create output directory if it doesn't exist + if _, err := os.Stat(outputDir); os.IsNotExist(err) { + err = os.Mkdir(outputDir, 0755) + if err != nil { + return "", fmt.Errorf("failed to create output directory: %w", err) + } + } + + // Write the image data to a file + outputPath := filepath.Join(outputDir, filename) + err := os.WriteFile(outputPath, imageData, 0644) + if err != nil { + return "", fmt.Errorf("failed to write image file: %w", err) + } + + return outputPath, nil +} + func main() { client := openai.NewClient(os.Getenv("OPENAI_API_KEY")) - respUrl, err := client.CreateImage( + res, err := client.CreateImage( context.Background(), openai.ImageRequest{ - Prompt: "Parrot on a skateboard performs a trick, cartoon style, natural light, high detail", - Size: openai.CreateImageSize256x256, - ResponseFormat: openai.CreateImageResponseFormatURL, - N: 1, + Prompt: "Parrot on a skateboard performing a trick. Large bold text \"SKATE MASTER\" banner at the bottom of the image. Cartoon style, natural light, high detail", + Background: openai.CreateImageBackgroundTransparent, + Model: openai.CreateImageModelGptImage1, + Size: openai.CreateImageSize1024x1024, + N: 1, + Quality: openai.CreateImageQualityLow, + OutputCompression: 100, + OutputFormat: openai.CreateImageOutputFormatJPEG, + // ResponseFormat: openai.CreateImageResponseFormatB64JSON, }, ) + if err != nil { fmt.Printf("Image creation error: %v\n", err) return } - fmt.Println(respUrl.Data[0].URL) + + // Decode the base64 data + imageBase64 := res.Data[0].B64JSON + fmt.Printf("Base64 data: %s\n", imageBase64) + + imageBytes, err := base64.StdEncoding.DecodeString(res.Data[0].B64JSON) + if err != nil { + fmt.Printf("Base64 decode error: %v\n", err) + return + } + + // Save the image using the new function + outputPath, err := saveImageToFile(imageBytes, "examples/images", "generated_image.jpg") + if err != nil { + fmt.Printf("Error saving image: %v\n", err) + return + } + + fmt.Printf("Image saved to: %s\n", outputPath) } From 598e31faf7773df4162219aee019c0ecebedca8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Wed, 23 Apr 2025 15:51:36 -0500 Subject: [PATCH 3/7] style: missing period in comments --- image.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/image.go b/image.go index 4eb6e13de..d62622a35 100644 --- a/image.go +++ b/image.go @@ -39,31 +39,31 @@ const ( CreateImageQualityHD = "hd" CreateImageQualityStandard = "standard" - // gpt-image-1 only + // gpt-image-1 only. CreateImageQualityHigh = "high" CreateImageQualityMedium = "medium" CreateImageQualityLow = "low" ) const ( - // dall-e-3 only + // dall-e-3 only. CreateImageStyleVivid = "vivid" CreateImageStyleNatural = "natural" ) const ( - // gpt-image-1 only + // gpt-image-1 only. CreateImageBackgroundTransparent = "transparent" CreateImageBackgroundOpaque = "opaque" ) const ( - // gpt-image-1 only + // gpt-image-1 only. CreateImageModerationLow = "low" ) const ( - // gpt-image-1 only + // gpt-image-1 only. CreateImageOutputFormatPNG = "png" CreateImageOutputFormatJPEG = "jpeg" CreateImageOutputFormatWEBP = "webp" From 617d2681053853f2c0fadb8f73d031b85d49c3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Wed, 23 Apr 2025 21:08:37 -0500 Subject: [PATCH 4/7] feat: add missing fields to example --- examples/images/main.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/examples/images/main.go b/examples/images/main.go index aeec9056d..553a2a2d5 100644 --- a/examples/images/main.go +++ b/examples/images/main.go @@ -37,15 +37,24 @@ func main() { res, err := client.CreateImage( context.Background(), openai.ImageRequest{ - Prompt: "Parrot on a skateboard performing a trick. Large bold text \"SKATE MASTER\" banner at the bottom of the image. Cartoon style, natural light, high detail", - Background: openai.CreateImageBackgroundTransparent, - Model: openai.CreateImageModelGptImage1, - Size: openai.CreateImageSize1024x1024, - N: 1, - Quality: openai.CreateImageQualityLow, - OutputCompression: 100, + Prompt: "Parrot on a skateboard performing a trick. Large bold text \"SKATE MASTER\" banner at the bottom of the image. Cartoon style, natural light, high detail", + Model: openai.CreateImageModelGptImage1, + Size: openai.CreateImageSize1024x1024, + N: 1, + Quality: openai.CreateImageQualityLow, + // User: "", // + + // Only for GPT Image 1 OutputFormat: openai.CreateImageOutputFormatJPEG, + OutputCompression: 100, + Background: openai.CreateImageBackgroundTransparent, + // Moderation: openai.CreateImageModerationLow, + + // Only for dall-e-2 and dall-e-3 // ResponseFormat: openai.CreateImageResponseFormatB64JSON, + + // Only for dall-e 3 + // Style: openai.CreateImageStyleVivid, }, ) @@ -64,7 +73,6 @@ func main() { return } - // Save the image using the new function outputPath, err := saveImageToFile(imageBytes, "examples/images", "generated_image.jpg") if err != nil { fmt.Printf("Error saving image: %v\n", err) From 286d79c3c175025209298af25173baf17d86bb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Wed, 23 Apr 2025 21:08:56 -0500 Subject: [PATCH 5/7] docs: add GPT Image 1 to README --- README.md | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 57d1d35bf..609dd25ba 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This library provides unofficial Go clients for [OpenAI API](https://platform.op * ChatGPT 4o, o1 * GPT-3, GPT-4 -* DALL·E 2, DALL·E 3 +* DALL·E 2, DALL·E 3, GPT Image 1 * Whisper ## Installation @@ -357,6 +357,68 @@ func main() { ``` +
+GPT Image 1 image generation + +```go +package main + +import ( + "context" + "encoding/base64" + "fmt" + "os" + + openai "github.com/sashabaranov/go-openai" +) + +func main() { + c := openai.NewClient("your token") + ctx := context.Background() + + req := openai.ImageRequest{ + Prompt: "Parrot on a skateboard performing a trick. Large bold text \"SKATE MASTER\" banner at the bottom of the image. Cartoon style, natural light, high detail, 1:1 aspect ratio.", + Background: openai.CreateImageBackgroundOpaque, + Model: openai.CreateImageModelGptImage1, + Size: openai.CreateImageSize1024x1024, + N: 1, + Quality: op +enai.CreateImageQualityLow, + OutputCompression: 100, + OutputFormat: openai.CreateImageOutputFormatJPEG, + // Moderation: openai.CreateImageModerationLow, + // User: "", + + } + + resp, err := c.CreateImage(ctx, req) + if err != nil { + fmt.Printf("Image creation Image generation with GPT Image 1error: %v\n", err) + return + } + + fmt.Println("Image Base64:", resp.Data[0].B64JSON) + + // Decode the base64 data + imgBytes, err := base64.StdEncoding.DecodeString(resp.Data[0].B64JSON) + if err != nil { + fmt.Printf("Base64 decode error: %v\n", err) + return + } + + // Write image to file + outputPath := "generated_image.jpg" + err = os.WriteFile(outputPath, imgBytes, 0644) + if err != nil { + fmt.Printf("Failed to write image file: %v\n", err) + return + } + + fmt.Printf("The image was saved as %s\n", outputPath) +} +``` +
+
Configuring proxy From 9d1cdd1bea6528ee43f18a7954cab99a50382173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Mon, 28 Apr 2025 08:03:18 -0500 Subject: [PATCH 6/7] revert: keep `examples/images/main.go` unchanged --- examples/images/main.go | 69 +++++------------------------------------ 1 file changed, 7 insertions(+), 62 deletions(-) diff --git a/examples/images/main.go b/examples/images/main.go index 553a2a2d5..2bfeb7973 100644 --- a/examples/images/main.go +++ b/examples/images/main.go @@ -2,82 +2,27 @@ package main import ( "context" - "encoding/base64" "fmt" "os" - "path/filepath" "github.com/sashabaranov/go-openai" ) -// saveImageToFile saves image data to a file in the specified directory -// Returns the full path where the image was saved or an error -func saveImageToFile(imageData []byte, outputDir, filename string) (string, error) { - // Create output directory if it doesn't exist - if _, err := os.Stat(outputDir); os.IsNotExist(err) { - err = os.Mkdir(outputDir, 0755) - if err != nil { - return "", fmt.Errorf("failed to create output directory: %w", err) - } - } - - // Write the image data to a file - outputPath := filepath.Join(outputDir, filename) - err := os.WriteFile(outputPath, imageData, 0644) - if err != nil { - return "", fmt.Errorf("failed to write image file: %w", err) - } - - return outputPath, nil -} - func main() { client := openai.NewClient(os.Getenv("OPENAI_API_KEY")) - res, err := client.CreateImage( + respUrl, err := client.CreateImage( context.Background(), openai.ImageRequest{ - Prompt: "Parrot on a skateboard performing a trick. Large bold text \"SKATE MASTER\" banner at the bottom of the image. Cartoon style, natural light, high detail", - Model: openai.CreateImageModelGptImage1, - Size: openai.CreateImageSize1024x1024, - N: 1, - Quality: openai.CreateImageQualityLow, - // User: "", // - - // Only for GPT Image 1 - OutputFormat: openai.CreateImageOutputFormatJPEG, - OutputCompression: 100, - Background: openai.CreateImageBackgroundTransparent, - // Moderation: openai.CreateImageModerationLow, - - // Only for dall-e-2 and dall-e-3 - // ResponseFormat: openai.CreateImageResponseFormatB64JSON, - - // Only for dall-e 3 - // Style: openai.CreateImageStyleVivid, + Prompt: "Parrot on a skateboard performs a trick, cartoon style, natural light, high detail", + Size: openai.CreateImageSize256x256, + ResponseFormat: openai.CreateImageResponseFormatURL, + N: 1, }, ) - if err != nil { fmt.Printf("Image creation error: %v\n", err) return } - - // Decode the base64 data - imageBase64 := res.Data[0].B64JSON - fmt.Printf("Base64 data: %s\n", imageBase64) - - imageBytes, err := base64.StdEncoding.DecodeString(res.Data[0].B64JSON) - if err != nil { - fmt.Printf("Base64 decode error: %v\n", err) - return - } - - outputPath, err := saveImageToFile(imageBytes, "examples/images", "generated_image.jpg") - if err != nil { - fmt.Printf("Error saving image: %v\n", err) - return - } - - fmt.Printf("Image saved to: %s\n", outputPath) -} + fmt.Println(respUrl.Data[0].URL) +} \ No newline at end of file From 4519cdafe7513a638045fa6591aa7fccef6d4b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= Date: Tue, 29 Apr 2025 09:18:37 -0500 Subject: [PATCH 7/7] docs: remove unnecessary newline from example in README file --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 609dd25ba..77b85e519 100644 --- a/README.md +++ b/README.md @@ -382,13 +382,11 @@ func main() { Model: openai.CreateImageModelGptImage1, Size: openai.CreateImageSize1024x1024, N: 1, - Quality: op -enai.CreateImageQualityLow, + Quality: openai.CreateImageQualityLow, OutputCompression: 100, OutputFormat: openai.CreateImageOutputFormatJPEG, // Moderation: openai.CreateImageModerationLow, // User: "", - } resp, err := c.CreateImage(ctx, req)