L’API permet de générer et de modifier des images à partir de prompts textuels avec gpt-image-2.5-sunburst et gpt-image-2.5-flare. Choisissez Sunburst pour les workflows qui privilégient la précision des retouches, et Flare pour générer rapidement des images de qualité au quotidien. Deux API donnent accès à la génération d’images.
API Image
L’API Image propose deux points de terminaison aux fonctions distinctes.
Génération : générez des images à partir d’un prompt textuel, sans image de départ.
L’API Responses permet de générer des images au fil d’une conversation ou d’un workflow en plusieurs étapes. Elle propose la génération d’images sous forme d’outil intégré et accepte dans le contexte aussi bien les images fournies en entrée que celles produites en sortie.
Par rapport à l’API Image, elle offre deux possibilités supplémentaires.
Retouches successives : affinez une image au fil des prompts tout en préservant fidèlement ses détails.
Souplesse des entrées : pour fournir une image en entrée, vous pouvez aussi transmettre l’identifiant de son fichier au lieu des données en octets.
Pour savoir quels modèles principaux peuvent appeler l’outil de génération d’images, consultez la section Modèles compatibles.
Choix de l’API
Pour générer ou modifier une seule image à partir d’un seul prompt, choisissez l’API Image.
Pour permettre à vos utilisateurs de générer et de retoucher des images avec GPT Image au fil d’une conversation, choisissez l’API Responses.
Avec l’API Image, attribuez directement à model la valeur gpt-image-2.5-sunburst ou gpt-image-2.5-flare. Avec l’API Responses, sélectionnez un modèle principal compatible au premier niveau de la requête et indiquez gpt-image-2.5-sunburst ou gpt-image-2.5-flare dans le champ model de l’outil de génération d’images.
Les deux API permettent de personnaliser l’image de sortie en réglant la qualité, les dimensions, le format et la compression.
GPT-Image-2.6 propose Sunburst pour les travaux visuels qui exigent de la précision et Flare pour affiner rapidement une image par retouches successives. Avec l’API Image, les deux modèles permettent de régler la complexité, de guider les retouches à l’aide d’annotations et de générer des images SVG et des GIF animés. Les exemples préexistants ci-dessous utilisent GPT-Image-2.5.
Réglage de la complexité de l’image
Utilisez le champ complexity de la requête pour régler l’effort de planification du modèle avant le rendu. Une complexité faible peut convenir aux retouches ciblées, comme la modification d’un arrière-plan ou d’un panneau. Une complexité élevée peut être utile lorsque l’image contient beaucoup de texte, que la mise en page est complexe ou que les relations entre les objets sont importantes. Elle peut aussi augmenter la latence et entraîner des modifications indésirables. Comparez les résultats pour votre tâche.
Sunburst et Flare acceptent les niveaux de complexité low, medium et high. Si vous omettez complexity, les deux modèles utilisent high. Le paramètre distinct quality règle la qualité du rendu.
Le réglage de la complexité n’entraîne aucuns frais supplémentaires.
Sunburst a généré ces scènes de football en papier découpé à partir du même prompt, avec une qualité moyenne. Comparez le trophée, les tenues et l’emplacement de l’inscription « CHAMPIONS » selon le niveau de complexité.
Complexité faible
Complexité moyenne
Complexité élevée
Identifiants de sécurité
Si votre application s’adresse à des utilisateurs finaux individuels, incluez un safety_identifier stable qui préserve leur confidentialité dans chaque requête de génération d’images ou de modification d’images. Hachez le nom d’utilisateur ou l’adresse e-mail pour éviter de transmettre des données identifiantes, et limitez l’identifiant à 128 caractères. Les identifiants de sécurité sont recommandés, mais facultatifs.
Le paramètre user de l’API Images est obsolète. Transmettez le même identifiant dans safety_identifier. L’API continue d’accepter les requêtes existantes qui utilisent user. Un safety_identifier non vide a priorité sur user. Si safety_identifier est absent, vaut null ou contient une chaîne vide, l’API utilise user s’il est fourni.
Réglez le paramètre n pour générer plusieurs images en une seule requête. Par défaut, l’API renvoie une seule image.
API Image
Générer une image
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import OpenAI from "openai";import fs from "fs";const openai = new OpenAI();const prompt = `A children's book drawing of a veterinarian using a stethoscope tolisten to the heartbeat of a baby otter.`;const result = await openai.images.generate({ model: "gpt-image-2.5-sunburst", prompt,});// Save the image to a fileconst image_base64 = result.data[0].b64_json;const image_bytes = Buffer.from(image_base64, "base64");fs.writeFileSync("otter.png", image_bytes);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from openai import OpenAIimport base64client = OpenAI()prompt ="""A children's book drawing of a veterinarian using a stethoscope tolisten to the heartbeat of a baby otter."""result = client.images.generate(model="gpt-image-2.5-sunburst", prompt=prompt)image_base64 = result.data[0].b64_jsonimage_bytes = base64.b64decode(image_base64)# Save the image to a filewithopen("otter.png", "wb") as f: f.write(image_bytes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package mainimport ( "context" "encoding/base64" "os" "github.com/openai/openai-go/v3")func main() { client := openai.NewClient() result, err := client.Images.Generate(context.Background(), openai.ImageGenerateParams{ Model: openai.ImageModel("gpt-image-2.5-sunburst"), Prompt: "A children's book drawing of a veterinarian using a stethoscope to " + "listen to the heartbeat of a baby otter.", }) if err != nil { panic(err) } image, err := base64.StdEncoding.DecodeString(result.Data[0].B64JSON) if err != nil { panic(err) } if err := os.WriteFile("otter.png", image, 0o600); err != nil { panic(err) }}
1
2
3
4
5
6
7
8
9
10
11
12using OpenAI.Images;string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;string model = "gpt-image-2.5-sunburst";ImageClient client = new(model, key);GeneratedImage image = await client.GenerateImageAsync( "A children's book drawing of a veterinarian using a stethoscope to " + "listen to the heartbeat of a baby otter.");await File.WriteAllBytesAsync("otter.png", image.ImageBytes.ToArray());
1
2
3
4
5
6
7
8
9
10
11
12
13require "base64"require "openai"client = OpenAI::Client.newresult = client.images.generate( model: "gpt-image-2.5-sunburst", prompt: "A watercolor robot reading in a library")generated_image = result.data&.first or raise "No image returned"File.binwrite( "generated-image.png", Base64.strict_decode64(generated_image.b64_json))
1
2
3
4
5
6
7curl -X POST "https://api.openai.com/v1/images/generations" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-type: application/json" \ -d '{ "model": "gpt-image-2.5-sunburst", "prompt": "A children'\''s book drawing of a veterinarian using a stethoscope to listen to the heartbeat of a baby otter." }' | jq -r '.data[0].b64_json' | base64 --decode > otter.png
1
2
3
4
5openai images generate \ --model gpt-image-2.5-sunburst \ --prompt "A children's book drawing of a veterinarian using a stethoscope to listen to the heartbeat of a baby otter." \ --raw-output \ --transform 'data.0.b64_json' | base64 --decode > otter.png
API Responses
Générer une image
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import OpenAI from "openai";const openai = new OpenAI();const response = await openai.responses.create({ model: "gpt-6-astra", input: "Generate an image of gray tabby cat hugging an otter with an orange scarf", tools: [{ type: "image_generation", model: "gpt-image-2.5-sunburst" }],});// Save the image to a fileconst imageData = response.output .filter((output) => output.type === "image_generation_call") .map((output) => output.result);if (imageData.length > 0) { const imageBase64 = imageData[0]; const fs = await import("fs"); fs.writeFileSync("otter.png", Buffer.from(imageBase64, "base64"));}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22from openai import OpenAIimport base64client = OpenAI()response = client.responses.create(model="gpt-6-astra",input="Generate an image of gray tabby cat hugging an otter with an orange scarf",tools=[{"type": "image_generation", "model": "gpt-image-2.5-sunburst"}],)# Save the image to a fileimage_data = [ output.resultfor output in response.outputif output.type =="image_generation_call"]if image_data: image_base64 = image_data[0]withopen("otter.png", "wb") as f: f.write(base64.b64decode(image_base64))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42package mainimport ( "context" "encoding/base64" "os" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/responses")func main() { client := openai.NewClient() response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{ Model: "gpt-6-astra", Input: responses.ResponseNewParamsInputUnion{ OfString: openai.String("Generate an image of gray tabby cat hugging an otter with an orange scarf"), }, Tools: []responses.ToolUnionParam{{OfImageGeneration: &responses.ToolImageGenerationParam{Model: "gpt-image-2.5-sunburst"}}}, }) if err != nil { panic(err) } saveFirstGeneratedImage(response, "otter.png")}func saveFirstGeneratedImage(response *responses.Response, filename string) { for _, output := range response.Output { if output.Type != "image_generation_call" { continue } image, err := base64.StdEncoding.DecodeString(output.AsImageGenerationCall().Result) if err != nil { panic(err) } if err := os.WriteFile(filename, image, 0o600); err != nil { panic(err) } return } panic("response did not include an image generation call")}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);CreateResponseOptions options = new() { Model = "gpt-6-astra" };options.InputItems.Add( ResponseItem.CreateUserMessageItem( "Generate an image of a gray tabby cat hugging an otter with an orange scarf." ));options.Tools.Add(ResponseTool.CreateImageGenerationTool(model: "gpt-image-2.5-sunburst"));ResponseResult response = await client.CreateResponseAsync(options);ImageGenerationCallResponseItem image = response .OutputItems.OfType<ImageGenerationCallResponseItem>() .FirstOrDefault() ?? throw new InvalidOperationException("No generated image was returned.");await File.WriteAllBytesAsync("otter.png", image.ImageResultBytes.ToArray());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24require "base64"require "openai"client = OpenAI::Client.newresponse = client.responses.create( model: "gpt-6-astra", input: "Generate an image of a gray tabby cat hugging an otter with an orange scarf.", tools: [ { type: :image_generation, model: "gpt-image-2.5-sunburst" } ])image_call = response.output.find do |item| item.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall)endunless image_call.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall) raise "No image generation call returned"endencoded_image = image_call.result or raise "No image returned"File.binwrite("otter.png", Base64.strict_decode64(encoded_image))
Génération d’images en plusieurs échanges
Avec l’API Responses, vous pouvez générer des images au fil d’une conversation en incluant dans le contexte les résultats des appels de génération d’images (l’identifiant de l’image suffit), ou en utilisant le paramètre previous_response_id.
Vous pouvez ainsi affiner vos prompts, donner de nouvelles instructions et faire évoluer l’image d’un échange à l’autre.
Avec l’outil de génération d’images de l’API Responses, les modèles compatibles peuvent choisir de générer une nouvelle image ou d’en modifier une déjà présente dans la conversation. Le paramètre facultatif action contrôle ce comportement. Conservez action: "auto" pour laisser le modèle choisir, utilisez action: "generate" pour toujours créer une nouvelle image, ou action: "edit" pour imposer la modification lorsqu’une image figure dans le contexte.
Imposer la création d’une image avec action
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import OpenAI from "openai";const openai = new OpenAI();const response = await openai.responses.create({ model: "gpt-6-astra", input: "Generate an image of gray tabby cat hugging an otter with an orange scarf", tools: [ { type: "image_generation", model: "gpt-image-2.5-sunburst", action: "generate" }, ],});// Save the image to a fileconst imageData = response.output .filter((output) => output.type === "image_generation_call") .map((output) => output.result);if (imageData.length > 0) { const imageBase64 = imageData[0]; const fs = await import("fs"); fs.writeFileSync("otter.png", Buffer.from(imageBase64, "base64"));}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24from openai import OpenAIimport base64client = OpenAI()response = client.responses.create(model="gpt-6-astra",input="Generate an image of gray tabby cat hugging an otter with an orange scarf",tools=[ {"type": "image_generation", "model": "gpt-image-2.5-sunburst", "action": "generate"} ],)# Save the image to a fileimage_data = [ output.resultfor output in response.outputif output.type =="image_generation_call"]if image_data: image_base64 = image_data[0]withopen("otter.png", "wb") as f: f.write(base64.b64decode(image_base64))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package mainimport ( "context" "encoding/base64" "os" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/responses")func main() { client := openai.NewClient() response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{ Model: "gpt-6-astra", Input: responses.ResponseNewParamsInputUnion{ OfString: openai.String("Generate an image of gray tabby cat hugging an otter with an orange scarf"), }, Tools: []responses.ToolUnionParam{{OfImageGeneration: &responses.ToolImageGenerationParam{Model: "gpt-image-2.5-sunburst", Action: "generate"}}}, }) if err != nil { panic(err) } for _, output := range response.Output { if output.Type != "image_generation_call" { continue } image, err := base64.StdEncoding.DecodeString(output.AsImageGenerationCall().Result) if err != nil { panic(err) } if err := os.WriteFile("otter.png", image, 0o600); err != nil { panic(err) } return } panic("response did not include an image generation call")}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);CreateResponseOptions options = new() { Model = "gpt-6-astra" };options.InputItems.Add( ResponseItem.CreateUserMessageItem( "Generate an image of a gray tabby cat hugging an otter with an orange scarf." ));options.Tools.Add( ResponseTool.CreateImageGenerationTool( model: "gpt-image-2.5-sunburst", action: ImageGenerationToolAction.Generate ));ResponseResult response = await client.CreateResponseAsync(options);ImageGenerationCallResponseItem image = response .OutputItems.OfType<ImageGenerationCallResponseItem>() .FirstOrDefault() ?? throw new InvalidOperationException("No generated image was returned.");await File.WriteAllBytesAsync("otter.png", image.ImageResultBytes.ToArray());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27require "base64"require "openai"client = OpenAI::Client.newresponse = client.responses.create( model: "gpt-6-astra", input: "Generate an image of a gray tabby cat hugging an otter with an orange scarf.", tools: [ { type: :image_generation, model: "gpt-image-2.5-sunburst", action: :generate } ])image_call = response.output.find do |item| item.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall)endunless image_call.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall) raise "No image generation call returned"endencoded_image = image_call.result or raise "No image returned"output_path = ENV.fetch("OPENAI_EXAMPLE_OUTPUT_PATH", "otter.png")File.binwrite(output_path, Base64.decode64(encoded_image))puts(output_path)
Si vous imposez edit sans fournir d’image dans le contexte, l’appel renvoie une erreur. Laissez action sur auto pour que le modèle choisisse entre génération et modification.
« Génère une image d’un chat tigré gris qui serre dans ses pattes une loutre portant une écharpe orange. »
« Donne maintenant à l’image un aspect réaliste. »
Diffusion en continu
L’API Responses et l’API Image prennent en charge la génération d’images en continu. Pour rendre l’expérience plus interactive, vous pouvez diffuser des images partielles à mesure que les API les génèrent.
Réglez le paramètre partial_images pour recevoir de 0 à 3 images partielles.
Si vous réglez partial_images sur 0, vous recevrez uniquement l’image finale.
Pour les valeurs supérieures à zéro, vous pouvez recevoir moins d’images partielles que demandé si l’image finale est prête plus tôt.
API Responses
Diffuser une image en continu
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33import OpenAI from "openai";import fs from "fs";const openai = new OpenAI();function saveBase64Image(filename, imageBase64) { const imageBuffer = Buffer.from(imageBase64, "base64"); fs.writeFileSync(filename, imageBuffer);}const stream = await openai.responses.create({ model: "gpt-6-astra", input: "Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape", stream: true, tools: [ { type: "image_generation", model: "gpt-image-2.5-sunburst", partial_images: 2 }, ],});for await (const event of stream) { if (event.type === "response.image_generation_call.partial_image") { const idx = event.partial_image_index; saveBase64Image(`river-partial-${idx}.png`, event.partial_image_b64); } else if (event.type === "response.completed") { const imageData = event.response.output .filter((output) => output.type === "image_generation_call") .map((output) => output.result); if (imageData.length > 0) { saveBase64Image("river-final.png", imageData[0]); } }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34from openai import OpenAIimport base64client = OpenAI()defsave_base64_image(filename, image_base64): image_bytes = base64.b64decode(image_base64)withopen(filename, "wb") as f: f.write(image_bytes)stream = client.responses.create(model="gpt-6-astra",input="Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape",stream=True,tools=[ {"type": "image_generation", "model": "gpt-image-2.5-sunburst", "partial_images": 2} ],)for event in stream:if event.type =="response.image_generation_call.partial_image": idx = event.partial_image_index save_base64_image(f"river-partial-{idx}.png", event.partial_image_b64)elif event.type =="response.completed": image_data = [ output.resultfor output in event.response.outputif output.type =="image_generation_call" ]if image_data: save_base64_image("river-final.png", image_data[0])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49package mainimport ( "context" "encoding/base64" "fmt" "os" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/responses")func main() { client := openai.NewClient() stream := client.Responses.NewStreaming(context.Background(), responses.ResponseNewParams{ Model: "gpt-6-astra", Input: responses.ResponseNewParamsInputUnion{ OfString: openai.String("Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape"), }, Tools: []responses.ToolUnionParam{{OfImageGeneration: &responses.ToolImageGenerationParam{Model: "gpt-image-2.5-sunburst", PartialImages: openai.Int(2)}}}, }) for stream.Next() { event := stream.Current() if event.Type == "response.image_generation_call.partial_image" { partial := event.AsResponseImageGenerationCallPartialImage() saveImage(fmt.Sprintf("river-partial-%d.png", partial.PartialImageIndex), partial.PartialImageB64) } if event.Type == "response.completed" { for _, output := range event.AsResponseCompleted().Response.Output { if output.Type == "image_generation_call" { saveImage("river-final.png", output.AsImageGenerationCall().Result) } } } } if err := stream.Err(); err != nil { panic(err) }}func saveImage(filename, encoded string) { image, err := base64.StdEncoding.DecodeString(encoded) if err != nil { panic(err) } if err := os.WriteFile(filename, image, 0o600); err != nil { panic(err) }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33require "base64"require "openai"client = OpenAI::Client.newstream = client.responses.stream( model: "gpt-6-astra", input: "Generate an image of a river made of white owl feathers.", tools: [ { type: :image_generation, model: "gpt-image-2.5-sunburst", partial_images: 2 } ])stream.each do |event| case event when OpenAI::Models::Responses::ResponseImageGenCallPartialImageEvent image = Base64.strict_decode64(event.partial_image_b64) File.binwrite("river-partial-#{event.partial_image_index}.png", image) when OpenAI::Models::Responses::ResponseCompletedEvent image_call = event.response.output.find do |item| item.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall) end next unless image_call.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall) File.binwrite( "river-final.png", Base64.strict_decode64(image_call.result) ) endend
API Image
Diffuser une image en continu
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import fs from "fs";import OpenAI from "openai";const openai = new OpenAI();const prompt = "Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape";const stream = await openai.images.generate({ prompt: prompt, model: "gpt-image-2.5-sunburst", stream: true, partial_images: 2,});for await (const event of stream) { if (event.type === "image_generation.partial_image") { const idx = event.partial_image_index; const imageBase64 = event.b64_json; const imageBuffer = Buffer.from(imageBase64, "base64"); fs.writeFileSync(`river${idx}.png`, imageBuffer); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from openai import OpenAIimport base64client = OpenAI()stream = client.images.generate(prompt="Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape",model="gpt-image-2.5-sunburst",stream=True,partial_images=2,)for event in stream:if event.type =="image_generation.partial_image": idx = event.partial_image_index image_base64 = event.b64_json image_bytes = base64.b64decode(image_base64)withopen(f"river{idx}.png", "wb") as f: f.write(image_bytes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40package mainimport ( "context" "encoding/base64" "fmt" "os" "github.com/openai/openai-go/v3")func main() { client := openai.NewClient() stream := client.Images.GenerateStreaming(context.Background(), openai.ImageGenerateParams{ Model: openai.ImageModel("gpt-image-2.5-sunburst"), Prompt: "Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape", PartialImages: openai.Int(2), }) for stream.Next() { event := stream.Current() if event.Type != "image_generation.partial_image" { continue } partial := event.AsImageGenerationPartialImage() saveImage(fmt.Sprintf("river%d.png", partial.PartialImageIndex), partial.B64JSON) } if err := stream.Err(); err != nil { panic(err) }}func saveImage(filename, encoded string) { image, err := base64.StdEncoding.DecodeString(encoded) if err != nil { panic(err) } if err := os.WriteFile(filename, image, 0o600); err != nil { panic(err) }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.images.ImageGenerateParams;import java.nio.file.Files;import java.nio.file.Path;import java.util.Base64;var params = ImageGenerateParams.builder() .prompt( "Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape") .model("gpt-image-2.5-sunburst") .partialImages(2) .build();try (var stream = client.images().generateStreaming(params)) { var events = stream.stream().iterator(); while (events.hasNext()) { var event = events.next(); if (event.generationPartialImage().isPresent()) { var partial = event.generationPartialImage().orElseThrow(); Files.write( Path.of("river" + partial.partialImageIndex() + ".png"), Base64.getDecoder().decode(partial.b64Json())); } }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16require "base64"require "openai"client = OpenAI::Client.newstream = client.images.generate_stream_raw( model: "gpt-image-2.5-sunburst", prompt: "A river made of white owl feathers in a winter landscape", partial_images: 2)stream.each do |event| next unless event.is_a?(OpenAI::Models::ImageGenPartialImageEvent) image = Base64.strict_decode64(event.b64_json) File.binwrite("river#{event.partial_image_index}.png", image)end
Résultat
Première image partielle
Deuxième image partielle
Image finale
Prompt : Dessine une magnifique rivière de plumes blanches de hibou qui serpente dans un paisible paysage d’hiver.
Prompt révisé
Lorsque vous utilisez l’outil de génération d’images de l’API Responses, le modèle principal (par exemple gpt-5.5) révise automatiquement votre prompt pour améliorer les résultats.
Vous trouverez le prompt révisé dans le champ revised_prompt de l’appel de génération d’images.
Réponse contenant le prompt révisé
1
2
3
4
5
6
7{"id": "ig_123","type": "image_generation_call","status": "completed","revised_prompt": "A gray tabby cat hugging an otter. The otter is wearing an orange scarf. Both animals are cute and friendly, depicted in a warm, heartwarming style.","result": "..."}
générer de nouvelles images à partir d’images de référence ;
modifier certaines parties d’une image en envoyant l’image et un masque qui délimite les zones à remplacer.
Création d’une image à partir d’images de référence
Vous pouvez utiliser une ou plusieurs images de référence pour en générer une nouvelle.
Dans cet exemple, nous utilisons quatre images en entrée pour générer une image de panier cadeau contenant les articles représentés sur les images de référence.
API Responses
Avec l’API Responses, vous pouvez fournir des images en entrée de trois façons :
Indiquez l’URL complète de l’image.
Fournissez une URL de données contenant l’image encodée en Base64.
Indiquez l’identifiant d’un fichier créé avec l’API Files.
Créez un fichier
Créez un fichier
Python
1
2
3
4
5
6
7
8
9
10
11
12
13import fs from "fs";import OpenAI from "openai";const openai = new OpenAI();async function createFile(filePath) { const fileContent = fs.createReadStream(filePath); const result = await openai.files.create({ file: fileContent, purpose: "vision", }); return result.id;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58require "base64"require "openai"require "pathname"client = OpenAI::Client.newbase64_images = ["body-lotion.png", "soap.png"].map do |path| Base64.strict_encode64(File.binread(path))endfile_ids = [ client.files.create(file: Pathname("bath-bomb.png"), purpose: :vision).id, client.files.create(file: Pathname("incense-kit.png"), purpose: :vision).id]prompt = <<~PROMPT Generate a photorealistic image of a gift basket on a white background labeled 'Relax & Unwind' with a ribbon and handwriting-like font, containing all the items in the reference pictures.PROMPTresponse = client.responses.create( model: "gpt-6-astra", input: [ { role: :user, content: [ { type: :input_text, text: prompt }, *base64_images.map do |image| { type: :input_image, image_url: "data:image/png;base64,#{image}" } end, *file_ids.map do |file_id| { type: :input_image, file_id: file_id } end ] } ], tools: [ { type: :image_generation, model: "gpt-image-2.5-sunburst" } ])image_call = response.output.find do |item| item.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall)endunless image_call.is_a?(OpenAI::Models::Responses::ResponseOutputItem::ImageGenerationCall) raise "No image generation call returned"endFile.binwrite("gift-basket.png", Base64.strict_decode64(image_call.result))
API Image
Modifier une image
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37import fs from "fs";import OpenAI, { toFile } from "openai";const client = new OpenAI();const prompt = `Generate a photorealistic image of a gift basket on a white backgroundlabeled 'Relax & Unwind' with a ribbon and handwriting-like font,containing all the items in the reference pictures.`;const imageFiles = [ "fixtures/bath-bomb.png", "fixtures/body-lotion.png", "fixtures/incense-kit.png", "fixtures/soap.png",];const images = await Promise.all( imageFiles.map( async (file) => await toFile(fs.createReadStream(file), null, { type: "image/png", }) ));const response = await client.images.edit({ model: "gpt-image-2.5-sunburst", image: images, prompt,});// Save the image to a fileconst image_base64 = response.data[0].b64_json;const image_bytes = Buffer.from(image_base64, "base64");fs.writeFileSync("basket.png", image_bytes);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import base64from openai import OpenAIclient = OpenAI()prompt ="""Generate a photorealistic image of a gift basket on a white backgroundlabeled 'Relax & Unwind' with a ribbon and handwriting-like font,containing all the items in the reference pictures."""result = client.images.edit(model="gpt-image-2.5-sunburst",image=[open("body-lotion.png", "rb"),open("bath-bomb.png", "rb"),open("incense-kit.png", "rb"),open("soap.png", "rb"), ],prompt=prompt,)image_base64 = result.data[0].b64_jsonimage_bytes = base64.b64decode(image_base64)# Save the image to a filewithopen("gift-basket.png", "wb") as f: f.write(image_bytes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65package mainimport ( "context" "encoding/base64" "io" "os" "github.com/openai/openai-go/v3")func main() { client := openai.NewClient() files, closeFiles := openImages( "bath-bomb.png", "body-lotion.png", "incense-kit.png", "soap.png", ) defer closeFiles() response, err := client.Images.Edit(context.Background(), openai.ImageEditParams{ Model: openai.ImageModel("gpt-image-2.5-sunburst"), Image: openai.ImageEditParamsImageUnion{OfFileArray: files}, Prompt: "Generate a photorealistic image of a gift basket on a white background " + "labeled 'Relax & Unwind' with a ribbon and handwriting-like font, containing all the items in the reference pictures.", }) if err != nil { panic(err) } saveImage("basket.png", response.Data[0].B64JSON)}func openImages(names ...string) ([]io.Reader, func()) { images := make([]io.Reader, 0, len(names)) files := make([]*os.File, 0, len(names)) for _, name := range names { file, err := os.Open(name) if err != nil { closeFiles(files) panic(err) } images = append(images, openai.File(file, name, "image/png")) files = append(files, file) } return images, func() { closeFiles(files) }}func closeFiles(files []*os.File) { for _, file := range files { if err := file.Close(); err != nil { panic(err) } }}func saveImage(filename, encoded string) { image, err := base64.StdEncoding.DecodeString(encoded) if err != nil { panic(err) } if err := os.WriteFile(filename, image, 0o600); err != nil { panic(err) }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.core.MultipartField;import com.openai.models.images.ImageEditParams;import java.io.IOException;import java.io.InputStream;import java.nio.file.Files;import java.nio.file.Path;import java.util.Base64;import java.util.List;Path lotion = Path.of(System.getenv("OPENAI_EXAMPLE_IMAGE_PATH"));Path soap = Path.of(System.getenv("OPENAI_EXAMPLE_IMAGE_PATH_2"));Path bathBomb = Path.of(System.getenv("OPENAI_EXAMPLE_IMAGE_PATH_3"));Path incense = Path.of(System.getenv("OPENAI_EXAMPLE_IMAGE_PATH_4"));try (InputStream lotionImage = Files.newInputStream(lotion); InputStream bathBombImage = Files.newInputStream(bathBomb); InputStream incenseImage = Files.newInputStream(incense); InputStream soapImage = Files.newInputStream(soap)) { var images = client .images() .edit( ImageEditParams.builder() .model("gpt-image-2.5-sunburst") .image( MultipartField.<ImageEditParams.Image>builder() .value( ImageEditParams.Image.ofInputStreams( List.of(lotionImage, bathBombImage, incenseImage, soapImage))) .contentType("image/png") .filename("gift-basket-reference.png") .build()) .prompt( """ Generate a photorealistic image of a gift basket on a white background labeled 'Relax & Unwind' with a ribbon and handwriting-like font, containing all the items in the reference pictures. """) .build()); Files.write( Path.of("gift-basket.png"), Base64.getDecoder().decode(images.data().orElseThrow().get(0).b64Json().orElseThrow()));}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19require "base64"require "openai"require "pathname"client = OpenAI::Client.newimages = %w[body-lotion.png bath-bomb.png incense-kit.png soap.png].map do |path| OpenAI::FilePart.new(Pathname(path), content_type: "image/png")endresult = client.images.edit( image: images, model: "gpt-image-2.5-sunburst", prompt: <<~PROMPT Generate a photorealistic image of a gift basket on a white background labeled 'Relax & Unwind' with a ribbon and handwriting-like font, containing all the items in the reference pictures. PROMPT)generated_image = result.data&.first or raise "No image returned"File.binwrite("gift-basket.png", Base64.strict_decode64(generated_image.b64_json))
1
2
3
4
5
6
7
8
9
10curl -s -D >(grep -i x-request-id >&2) \ -o >(jq -r '.data[0].b64_json' | base64 --decode > gift-basket.png) \ -X POST "https://api.openai.com/v1/images/edits" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -F "model=gpt-image-2.5-sunburst" \ -F "image[]=@body-lotion.png" \ -F "image[]=@bath-bomb.png" \ -F "image[]=@incense-kit.png" \ -F "image[]=@soap.png" \ -F 'prompt=Generate a photorealistic image of a gift basket on a white background labeled "Relax & Unwind" with a ribbon and handwriting-like font, containing all the items in the reference pictures'
1
2
3
4
5
6
7
8
9openai images edit \ --model gpt-image-2.5-sunburst \ --image body-lotion.png \ --image bath-bomb.png \ --image incense-kit.png \ --image soap.png \ --prompt 'Generate a photorealistic image of a gift basket on a white background labeled "Relax & Unwind" with a ribbon and handwriting-like font, containing all the items in the reference pictures' \ --raw-output \ --transform 'data.0.b64_json' | base64 --decode > gift-basket.png
Retouches guidées par des annotations
Utilisez le point de terminaison POST /v1/images/edits de l’API Image pour guider les retouches à l’aide d’annotations avec les modèles GPT-Image-2.5 et GPT-Image-2.6 compatibles. Pour retoucher une zone précise avec l’API Responses, utilisez un masque. Indiquez la zone à modifier sur un calque d’annotations et décrivez la modification dans prompt.
Pour suivre cet exemple, téléchargez la photo de la cuisine et le calque transparent dans le même répertoire. Le cercle tracé sur le calque entoure le vase dont vous allez changer la couleur.
Modifier le vase entouré avec l’API Image
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import base64from pathlib import Pathfrom openai import OpenAIclient = OpenAI()overlay = Path("markup-vase-overlay-gpt-image-2-6.png")withopen("kitchen.webp", "rb") as image, overlay.open("rb") as markup: result = client.images.edit(model="gpt-image-2.6-flare",image=("kitchen.webp", image, "image/webp"),markup=(overlay.name, markup, "image/png"),quality="medium",prompt=("Recolor the striped vase inside the red circle to solid cobalt blue ceramic. ""Keep its shape, the dried stems, and the rest of the kitchen unchanged. ""Remove the red circle from the finished photo." ), )Path("vase.png").write_bytes(base64.b64decode(result.data[0].b64_json))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31client := openai.NewClient()image, err := os.Open("kitchen.webp")if err != nil { panic(err)}defer image.Close()markup, err := os.Open("markup-vase-overlay-gpt-image-2-6.png")if err != nil { panic(err)}defer markup.Close()response, err := client.Images.Edit(context.Background(), openai.ImageEditParams{ Model: openai.ImageModel("gpt-image-2.6-flare"), Image: openai.ImageEditParamsImageUnion{OfFile: openai.File(image, "kitchen.webp", "image/webp")}, Markup: openai.File(markup, "markup-vase-overlay-gpt-image-2-6.png", "image/png"), Quality: "medium", Prompt: "Recolor the striped vase inside the red circle to solid cobalt blue ceramic. " + "Keep its shape, the dried stems, and the rest of the kitchen unchanged. " + "Remove the red circle from the finished photo.",})if err != nil { panic(err)}result, err := base64.StdEncoding.DecodeString(response.Data[0].B64JSON)if err != nil { panic(err)}if err := os.WriteFile("vase.png", result, 0o600); err != nil { panic(err)}
1
2
3
4
5
6
7
8
9
10set -euo pipefailcurl --fail --silent --show-error https://api.openai.com/v1/images/edits \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -F model=gpt-image-2.6-flare \ -F quality=medium \ -F 'image=@kitchen.webp;type=image/webp' \ -F 'markup=@markup-vase-overlay-gpt-image-2-6.png;type=image/png' \ -F 'prompt=Recolor the striped vase inside the red circle to solid cobalt blue ceramic. Keep its shape, the dried stems, and the rest of the kitchen unchanged. Remove the red circle from the finished photo.' | jq -er '.data[0].b64_json' | base64 --decode > vase.png
Photo avec le calque d’annotations
Résultat avec Flare
Gardez l’image d’origine en première position parmi les images d’entrée.
Créez un fichier PNG transparent distinct contenant vos cercles, croquis ou autres annotations. Une fois l’orientation appliquée, le calque d’annotations et la première image doivent avoir la même largeur et la même hauteur. Le PNG doit contenir des pixels transparents. Ne le fusionnez pas avec l’image d’origine.
Envoyez le calque d’annotations dans markup. Dans une requête multipart, vous pouvez transmettre directement le fichier. Dans une requête JSON, fournissez un objet contenant exactement un des deux champs image_url ou file_id. Le champ image_url accepte une URL HTTPS ou une URL de données en base64. Dans les requêtes de modification au format JSON, utilisez images pour le tableau des images d’entrée.
Décrivez la modification souhaitée et les détails à préserver. Vérifiez le résultat avant de l’utiliser.
Les annotations s’appliquent à la première image d’entrée. Les images supplémentaires servent de références. La première image et le calque d’annotations peuvent contenir au maximum 16 777 216 pixels chacun. La taille du fichier d’annotations est également limitée à 50 Mo. Ne combinez pas markup avec mask.
Modification d’une image à l’aide d’un masque
Fournissez un masque pour indiquer quelle partie de l’image modifier.
Lorsque vous utilisez un masque avec GPT Image, le modèle reçoit des instructions supplémentaires pour guider la retouche.
Avec GPT Image, le masquage repose entièrement sur le prompt. Le modèle se sert du masque comme repère, mais peut s’écarter de ses contours exacts.
Si vous fournissez plusieurs images en entrée, le masque s’applique à la première.
API Responses
Modifier une image à l’aide d’un masque
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54import fs from "fs";import OpenAI from "openai";const openai = new OpenAI();async function createFile(filePath) { const result = await openai.files.create({ file: fs.createReadStream(filePath), purpose: "vision", }); return result.id;}const fileId = await createFile("fixtures/sunlit_lounge.png");const maskId = await createFile("fixtures/mask.png");const response = await openai.responses.create({ model: "gpt-6-astra", input: [ { role: "user", content: [ { type: "input_text", text: "generate an image of the same sunlit indoor lounge area with a pool but the pool should contain a flamingo", }, { type: "input_image", file_id: fileId, detail: "auto", }, ], }, ], tools: [ { type: "image_generation", model: "gpt-image-2.5-sunburst", quality: "high", input_image_mask: { file_id: maskId, }, }, ],});const imageData = response.output .filter((output) => output.type === "image_generation_call") .map((output) => output.result);if (imageData.length > 0) { const imageBase64 = imageData[0]; fs.writeFileSync("lounge.png", Buffer.from(imageBase64, "base64"));}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54from openai import OpenAIimport base64client = OpenAI()defcreate_file(file_path):withopen(file_path, "rb") as file_content: result = client.files.create(file=file_content, purpose="vision")return result.idfileId = create_file("sunlit_lounge.png")maskId = create_file("mask.png")response = client.responses.create(model="gpt-6-astra",input=[ {"role": "user","content": [ {"type": "input_text","text": "generate an image of the same sunlit indoor lounge area with a pool but the pool should contain a flamingo", }, {"type": "input_image","file_id": fileId, }, ], }, ],tools=[ {"type": "image_generation","model": "gpt-image-2.5-sunburst","quality": "high","input_image_mask": {"file_id": maskId, }, }, ],)image_data = [ output.resultfor output in response.outputif output.type =="image_generation_call"]if image_data: image_base64 = image_data[0]withopen("lounge.png", "wb") as f: f.write(base64.b64decode(image_base64))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67package mainimport ( "context" "encoding/base64" "os" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/responses")func main() { client := openai.NewClient() imageID := uploadImage(client, "sunlit_lounge.png") maskID := uploadImage(client, "mask.png") response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{ Model: "gpt-6-astra", Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{ responses.ResponseInputItemParamOfMessage( responses.ResponseInputMessageContentListParam{ responses.ResponseInputContentParamOfInputText("Generate an image of the same sunlit indoor lounge area with a pool, but the pool should contain a flamingo."), {OfInputImage: &responses.ResponseInputImageParam{FileID: openai.String(imageID), Detail: responses.ResponseInputImageDetailAuto}}, }, responses.EasyInputMessageRoleUser, ), }}, Tools: []responses.ToolUnionParam{{OfImageGeneration: &responses.ToolImageGenerationParam{ Model: "gpt-image-2.5-sunburst", Quality: "high", InputImageMask: responses.ToolImageGenerationInputImageMaskParam{FileID: openai.String(maskID)}, }}}, }) if err != nil { panic(err) } saveFirstGeneratedImage(response, "lounge.png")}func uploadImage(client openai.Client, filename string) string { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() uploaded, err := client.Files.New(context.Background(), openai.FileNewParams{File: file, Purpose: openai.FilePurposeVision}) if err != nil { panic(err) } return uploaded.ID}func saveFirstGeneratedImage(response *responses.Response, filename string) { for _, output := range response.Output { if output.Type != "image_generation_call" { continue } image, err := base64.StdEncoding.DecodeString(output.AsImageGenerationCall().Result) if err != nil { panic(err) } if err := os.WriteFile(filename, image, 0o600); err != nil { panic(err) } return } panic("response did not include an image generation call")}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15require "openai"require "pathname"require "base64"client = OpenAI::Client.newimage = OpenAI::FilePart.new(Pathname("sunlit_lounge.png"), content_type: "image/png")mask = OpenAI::FilePart.new(Pathname("mask.png"), content_type: "image/png")result = client.images.edit( image: image, mask: mask, model: "gpt-image-2.5-sunburst", prompt: "A sunlit indoor lounge area with a pool containing a flamingo")generated_image = result.data&.first or raise "No image returned"File.binwrite("lounge.png", Base64.strict_decode64(generated_image.b64_json))
1
2
3
4
5
6
7
8curl -s -D >(grep -i x-request-id >&2) \ -o >(jq -r '.data[0].b64_json' | base64 --decode > lounge.png) \ -X POST "https://api.openai.com/v1/images/edits" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -F "model=gpt-image-2.5-sunburst" \ -F "mask=@mask.png" \ -F "image[]=@sunlit_lounge.png" \ -F 'prompt=A sunlit indoor lounge area with a pool containing a flamingo'
1
2
3
4
5
6
7openai images edit \ --model gpt-image-2.5-sunburst \ --image sunlit_lounge.png \ --mask mask.png \ --prompt "A sunlit indoor lounge area with a pool containing a flamingo" \ --raw-output \ --transform 'data.0.b64_json' | base64 --decode > out.png
Image
Masque
Résultat
Prompt : un espace de détente intérieur baigné de soleil, avec un flamant rose dans la piscine
Contraintes du masque
L’image à modifier et le masque doivent avoir le même format et les mêmes dimensions. Chaque fichier doit peser moins de 50 Mo.
L’image du masque doit aussi comporter un canal alpha. Si vous créez le masque dans un logiciel de retouche, veillez à l’enregistrer avec un canal alpha.
Vous pouvez ajouter un canal alpha à une image en noir et blanc par programmation.
Ajouter un canal alpha à un masque en noir et blanc
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21fromPILimport Imagefrom io import BytesIO# 1. Load your black & white mask as a grayscale imagemask = Image.open("mask.png").convert("L")# 2. Convert it to RGBA so it has space for an alpha channelmask_rgba = mask.convert("RGBA")# 3. Then use the mask itself to fill that alpha channelmask_rgba.putalpha(mask)# 4. Convert the mask into bytesbuf = BytesIO()mask_rgba.save(buf, format="PNG")mask_bytes = buf.getvalue()# 5. Save the resulting fileimg_path_mask_alpha ="mask_alpha.png"withopen(img_path_mask_alpha, "wb") as f: f.write(mask_bytes)
Vous pouvez configurer les options de sortie suivantes :
Dimensions : largeur et hauteur de l’image (par exemple 1024x1024 ou 1024x1536).
Qualité : qualité du rendu (par exemple low, medium ou high).
Format : format du fichier de sortie.
Compression : taux de compression (de 0 à 100 %) pour les formats JPEG et WebP.
Arrière-plan : transparent, opaque ou choisi automatiquement.
Les paramètres size, quality et background acceptent l’option auto, qui laisse le modèle choisir la valeur la plus adaptée au prompt.
Dimensions et qualité
Les modèles gpt-image-2.5-sunburst et gpt-image-2.5-flare ajoutent les niveaux de qualité xhigh et max. Tous deux utilisent auto par défaut. Les modèles GPT Image antérieurs acceptent des niveaux de qualité allant jusqu’à high.
Les deux modèles acceptent également des dimensions personnalisées sous forme de chaînes au format WIDTHxHEIGHT, par exemple 1536x864. La largeur et la hauteur doivent être des multiples de 16 et ne doivent pas dépasser 3 840 pixels chacune. Le rapport largeur/hauteur doit être compris entre 1:3 et 3:1. Le nombre total de pixels doit être compris entre 655 360 et 8 294 400 (4K). Les résolutions supérieures à 2560x1440 sont expérimentales.
Pour obtenir un arrière-plan transparent avec l’un ou l’autre modèle, indiquez background: "transparent" et utilisez output_format: "png" ou "webp".
Utilisez quality: "low" pour produire rapidement des ébauches. Pour les images finales, comparez les niveaux de qualité supérieurs afin de trouver le bon équilibre entre niveau de détail, latence et coût.
Format de sortie
L’API Image renvoie les données de l’image encodées en base64.
Le format par défaut est png, mais vous pouvez aussi demander jpeg ou webp.
Avec jpeg ou webp, le paramètre output_compression permet de régler le taux de compression de 0 à 100 %. Par exemple, output_compression=50 applique une compression de 50 % à l’image.
Le format jpeg est plus rapide que le format png. Privilégiez-le si la latence est un critère important.
Génération d’images SVG
Indiquez output_format: "svg" dans votre requête POST /v1/images/generations. Utilisez le format SVG pour les éléments graphiques dont vous souhaitez pouvoir modifier les tracés, les formes et les couleurs, comme les icônes et les illustrations.
Réglez n sur 1. Le format de sortie SVG ne prend en charge ni la diffusion en continu, ni les images partielles, ni output_compression. Le point de terminaison de modification d’images ne produit pas de SVG et n’accepte pas de fichier SVG comme image matricielle en entrée.
L’API crée une image de référence, puis l’utilise pour produire le SVG. Le paramètre quality règle la qualité de cette image de référence. Décodez la valeur en base64 de data[0].b64_json et enregistrez les octets obtenus, qui représentent du XML en UTF-8, dans un fichier portant l’extension .svg. Le document renvoyé contient des éléments vectoriels statiques. Il ne prend en charge ni les scripts, ni les ressources externes, ni les images matricielles intégrées.
Flare et Sunburst ont généré ces logos SVG à partir du même prompt demandant un logo pour la boulangerie Field & Flour.
GPT-Image-2.6 Flare
GPT-Image-2.6 Sunburst
Génération de GIF animés
Indiquez output_format: "gif" dans votre requête POST /v1/images/generations ou POST /v1/images/edits. Dans votre prompt, décrivez le sujet, le mouvement et la boucle souhaitée. Pour guider l’animation à l’aide d’images de référence fixes, envoyez ces images au point de terminaison de modification d’images.
Pour obtenir un GIF avec l’un ou l’autre point de terminaison, utilisez les champs de requête suivants :
Champ
Valeurs
Valeur par défaut
frame_count
De 2 à 16 images
9
frame_duration_ms
De 20 à 2 000 millisecondes par image, avec un arrondi au multiple de 10 ms le plus proche
200
size
auto ou WIDTHxHEIGHT, avec une largeur et une hauteur strictement positives, multiples de 16
auto
size indique les dimensions de chaque image de l’animation finale. Le nombre d’images, leurs dimensions et le nombre d’animations doivent respecter les limites de taille du modèle et le nombre total de pixels autorisé par requête. Si la requête dépasse ces limites, réduisez frame_count, les dimensions des images ou n. Utilisez auto pour laisser l’API choisir des dimensions compatibles avec les limites du modèle.
La réponse contient l’animation finale. Pour chaque résultat, décodez la valeur en base64 du champ b64_json et enregistrez les octets obtenus dans un fichier portant l’extension .gif. Le format de sortie GIF ne permet ni la diffusion en continu, ni les images partielles, ni le réglage de output_compression. Utilisez frame_count et frame_duration_ms uniquement pour une sortie au format GIF.
Sunburst a généré cette animation de lanterne avec frame_count=9 et frame_duration_ms=200. Le singe reprend sa pose initiale au bout de 1,8 seconde.
Limites
Les modèles GPT Image sont des modèles de génération d’images puissants et polyvalents, mais présentent encore certaines limites.
Latence : le traitement d’un prompt complexe peut prendre jusqu’à deux minutes.
Rendu du texte : malgré des progrès importants, le modèle peut encore avoir du mal à placer le texte avec précision et à le rendre lisible.
Cohérence : le modèle peut produire des images cohérentes, mais l’apparence d’un personnage récurrent ou d’un élément de marque peut parfois varier d’une génération à l’autre.
Maîtrise de la composition : le modèle suit mieux les instructions, mais peut avoir du mal à placer précisément les éléments lorsque la composition obéit à une structure ou à une mise en page particulière.
Modération du contenu
Tous les prompts et toutes les images générées sont filtrés conformément à notre politique d’utilisation.
Pour la génération d’images avec les modèles GPT Image, le paramètre moderation permet de régler le niveau de filtrage. Il accepte deux valeurs.
auto (par défaut) : filtrage standard visant à limiter la création de certaines catégories de contenus potentiellement inadaptés à l’âge du public.
low : filtrage moins restrictif.
Gestion des requêtes bloquées et des autres erreurs
Traitez les échecs de génération d’images comme les autres erreurs de l’API. Vérifiez le code de statut HTTP ou le type d’exception du SDK, consignez l’identifiant de la requête et consultez le guide des codes d’erreur en cas d’échec d’authentification, de dépassement de quota ou de limite de débit, ou d’erreur serveur. Pour les erreurs temporaires de limite de débit ou de serveur, réessayez en espaçant progressivement les tentatives. Ne relancez pas automatiquement une requête en cas d’erreur de quota ou d’erreur de génération d’images qui exige que l’utilisateur modifie la requête.
Certaines erreurs de génération d’images peuvent être corrigées par l’utilisateur. L’API peut alors renvoyer error.type = "image_generation_user_error". Dans ce cas, ne relancez pas automatiquement la requête sans modifier le prompt ou les images d’entrée. Pour distinguer ces erreurs dans votre code, utilisez le champ stable error.code.
Lorsque error.code = "moderation_blocked", l’erreur peut aussi inclure un objet facultatif error.moderation_details.
L’objet moderation_details fournit des indications générales pour le débogage sans exposer les libellés ni les scores des classificateurs internes.
Le champ moderation_stage peut prendre les valeurs suivantes :
input : le blocage provient du prompt ou des données d’entrée de la requête.
output : le blocage provient d’une image générée ou d’une étape ultérieure de modération des sorties.
unknown : valeur de repli utilisée dans les rares cas où l’origine du blocage est difficile à déterminer.
Le champ categories contient des libellés publics correspondant à de grandes catégories. Vous pouvez par exemple y trouver harassment, self-harm, sexual ou violence.
Dans la plupart des applications, gardez le message principal destiné à l’utilisateur suffisamment général. Utilisez moderation_details dans les journaux de développement, les workflows d’assistance et les analyses, ou pour suggérer des corrections simples.
Gérer les erreurs de génération d’images bloquées par la modération
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42import OpenAI from"openai";constopenai=newOpenAI();try {// The same error handling pattern applies to image generation requests,// image edits, and Responses API tool calls that generate images.await openai.images.generate({ model: "gpt-image-2.5-sunburst", prompt: "Create a poster humiliating my coworker with insulting captions", });} catch (error) {if (error?.code !=="moderation_blocked") {throw error; }constmoderationDetails= error.error?.moderation_details;constcategories= moderationDetails?.categories ?? [];conststage= moderationDetails?.moderation_stage;let hint ="This request could not be completed because it did not meet safety requirements.";if (categories.includes("harassment")) { hint ="Try removing abusive or targeting language and focus on neutral visual details instead."; } elseif (stage ==="input") { hint ="Try revising the prompt or input images and submit the request again."; } elseif (stage ==="output") { hint ="The generated result was blocked by a safety check. Try changing the prompt and generating again."; } console.error("Image generation blocked", { request_id: error?.requestID, code: error?.code, moderation_details: moderationDetails, }); console.log(hint);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40import openaifrom openai import OpenAIclient = OpenAI()try: # The same error handling pattern applies to image generation requests, # image edits, and Responses API tool calls that generate images. client.images.generate( model="gpt-image-2.5-sunburst", prompt="Create a poster humiliating my coworker with insulting captions", )except openai.BadRequestError as error: if error.code != "moderation_blocked": raise error_body = error.body if isinstance(error.body, dict) else {} moderation_details = error_body.get("moderation_details") or {} categories = moderation_details.get("categories") or [] stage = moderation_details.get("moderation_stage") hint = "This request could not be completed because it did not meet safety requirements." if "harassment" in categories: hint = "Try removing abusive or targeting language and focus on neutral visual details instead." elif stage == "input": hint = "Try revising the prompt or input images and submit the request again." elif stage == "output": hint = "The generated result was blocked by a safety check. Try changing the prompt and generating again." print( "Image generation blocked", { "request_id": error.request_id, "code": error.code, "moderation_details": moderation_details, }, ) print(hint)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48package mainimport ( "context" "encoding/json" "errors" "fmt" "slices" "github.com/openai/openai-go/v3")func main() { client := openai.NewClient() _, err := client.Images.Generate(context.Background(), openai.ImageGenerateParams{ Model: openai.ImageModel("gpt-image-2.5-sunburst"), Prompt: "Create a poster humiliating my coworker with insulting captions", }) if err == nil { return } var apiError *openai.Error if !errors.As(err, &apiError) || apiError.Code != "moderation_blocked" { panic(err) } var body struct { ModerationDetails struct { Categories []string `json:"categories"` ModerationStage string `json:"moderation_stage"` } `json:"moderation_details"` } if err := json.Unmarshal([]byte(apiError.RawJSON()), &body); err != nil { panic(err) } hint := "This request could not be completed because it did not meet safety requirements." if slices.Contains(body.ModerationDetails.Categories, "harassment") { hint = "Try removing abusive or targeting language and focus on neutral visual details instead." } else if body.ModerationDetails.ModerationStage == "input" { hint = "Try revising the prompt or input images and submit the request again." } else if body.ModerationDetails.ModerationStage == "output" { hint = "The generated result was blocked by a safety check. Try changing the prompt and generating again." } fmt.Printf("Image generation blocked (%s): %s\n", apiError.Code, hint)}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.errors.BadRequestException;import com.openai.models.images.ImageGenerateParams;import java.util.List;import java.util.Map;try { var images = client .images() .generate( ImageGenerateParams.builder() .model("gpt-image-2.5-sunburst") .prompt("Create a poster humiliating my coworker with insulting captions") .build()); System.out.println(images.data().orElseThrow().get(0).b64Json().orElseThrow());} catch (BadRequestException error) { if (!error.code().orElse("").equals("moderation_blocked")) { throw error; } Map<?, ?> body = error.body().convert(Map.class); Object detailsValue = body.get("moderation_details"); Map<?, ?> details = detailsValue instanceof Map<?, ?> values ? values : Map.of(); Object categories = details.get("categories"); Object stage = details.get("moderation_stage"); String hint = "This request did not meet safety requirements."; if (categories instanceof List<?> values && values.contains("harassment")) { hint = "Remove abusive or targeting language and focus on neutral visual details."; } else if ("input".equals(stage)) { hint = "Revise the prompt or input images, then submit the request again."; } else if ("output".equals(stage)) { hint = "Change the prompt and generate again; the generated result was blocked."; } System.err.println("Image generation blocked (" + error.code().orElseThrow() + "): " + hint);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28require "openai"client = OpenAI::Client.newbegin client.images.generate( model: "gpt-image-2.5-sunburst", prompt: "Create a poster humiliating my coworker with insulting captions" )rescue OpenAI::Errors::BadRequestError => error raise unless error.code == "moderation_blocked" body = Hash.try_convert(error.body) || {} body = Hash.try_convert(body[:error] || body["error"]) || body moderation_details = body[:moderation_details] || body["moderation_details"] || {} categories = moderation_details[:categories] || moderation_details["categories"] || [] stage = moderation_details[:moderation_stage] || moderation_details["moderation_stage"] hint = "This request did not meet safety requirements." if categories.include?("harassment") hint = "Remove abusive or targeting language and focus on neutral visual details." elsif stage == "input" hint = "Revise the prompt or input images, then submit the request again." elsif stage == "output" hint = "Change the prompt and generate again; the generated result was blocked." end warn("Image generation blocked (#{error.code}): #{hint}")end
Modèles compatibles
Dans l’API Responses, gpt-5 et les modèles plus récents devraient prendre en charge l’outil de génération d’images. Consultez la fiche de votre modèle pour vérifier sa compatibilité avec cet outil.
Coût et latence
Coûts de GPT-Image-2.6
Les images en sortie coûtent 30 $ par million de tokens facturables. Utilisez le calculateur pour estimer le coût de sortie d’une image.
Les retouches guidées par des annotations sont facturées au même tarif par token que les autres retouches, sans supplément. Pour une sortie SVG, l’image de référence est facturée au tarif du modèle de génération d’images. Les tokens que le modèle de rédaction utilise pour produire le SVG sont facturés au tarif de ce dernier. Le coût total dépend du nombre de tokens consommés par chaque modèle.
Coûts de GPT-Image-2.5
Pour les requêtes envoyées à l’API Responses, le coût des tokens consommés par le modèle principal s’ajoute au coût de génération des images.
Les deux modèles GPT-Image-2.5 appliquent les mêmes tarifs par million de tokens : 8 $ pour les images en entrée, 2 $ pour les images en entrée mises en cache, 30 $ pour les images en sortie, 5 $ pour le texte en entrée et 1,25 $ pour le texte en entrée mis en cache. Consultez la grille tarifaire.
Utilisez le champ usage de la réponse pour mesurer la consommation de tokens selon vos prompts, les dimensions et la qualité choisies. Même si le tarif par token est identique, le coût par image peut varier, car la consommation de tokens dépend du modèle et du niveau de qualité. Pour des exemples de tarifs des modèles antérieurs, consultez la section Modèles GPT Image antérieurs.
Tarification des entrées mises en cache
Pour GPT-Image-2 et GPT-Image-2.5, le tarif des entrées mises en cache s’applique uniquement à l’outil de génération d’images de l’API Responses. Il ne s’applique pas aux requêtes envoyées directement à l’API Images, y compris à /v1/images/edits.
La facturation tient compte des entrées de génération d’images mises en cache, mais l’API Responses ne renvoie pas le nombre de tokens correspondants. Le champ usage de la réponse ne permet donc pas de vérifier si ces entrées ont été lues depuis le cache.
Calcul des coûts
Sélectionnez un modèle, un niveau de qualité et des dimensions pour estimer le nombre de tokens de sortie et le coût de l’image produite.
Pour les modèles Sunburst et Flare des familles GPT-Image-2.6 et GPT-Image-2.5, les niveaux de qualité disponibles sont low, medium, high, xhigh et max.
Pour gpt-image-2, les options sont low, medium et high.
À qualité égale, les modèles peuvent consommer des nombres de tokens différents, mais le tarif par token d’image en sortie est identique.
Pour cette estimation, indiquez des valeurs explicites de qualité et de dimensions. Avec auto, le résultat dépend de l’image générée.
ModèleModèleGPT-Image-2.6 (Sunburst and Flare)
Qualité
Tokens de sortie
823
Coût estimé par image générée
0,02469 $US
Par image, au tarif de 30 USD par million de tokens d’image en sortie. L’estimation exclut les tokens de texte et d’image en entrée ainsi que les images partielles diffusées en streaming.
Coût des images partielles
Si vous souhaitez diffuser la génération d’images en continu avec le paramètre partial_images, chaque image partielle coûte 100 tokens d’image en sortie supplémentaires.
Modèles GPT Image antérieurs
Les informations ci-dessous concernent les modèles antérieurs à Sunburst et Flare. Pour les nouvelles intégrations, utilisez GPT-Image-2.6 Sunburst ou Flare.
Paramètres de GPT-Image-2 et fidélité aux images d’entrée
Avec gpt-image-2, le paramètre size accepte toute résolution qui respecte les contraintes ci-dessous. Les images carrées sont généralement les plus rapides à générer.
Dimensions courantes
1024x1024 (carré)
1536x1024 (paysage)
1024x1536 (portrait)
2048x2048 (carré 2K)
2048x1152 (paysage 2K)
3840x2160 (paysage 4K)
2160x3840 (portrait 4K)
auto (par défaut)
Contraintes de dimensions
La longueur du plus grand côté doit être inférieure ou égale à
3840px
La largeur et la hauteur doivent être des multiples de 16px
Le rapport entre le côté le plus long et le côté le plus court ne doit pas dépasser 3:1
Le nombre total de pixels doit être au moins égal à 655,360 et ne pas dépasser
8,294,400
Niveaux de qualité
low
medium
high
auto (par défaut)
Fidélité aux images d’entrée
Le paramètre input_fidelity détermine dans quelle mesure le modèle préserve les détails des images d’entrée lors des retouches et de la génération à partir d’images de référence. Pour gpt-image-2, omettez ce paramètre. L’API ne permet pas de le modifier, car le modèle traite automatiquement chaque image d’entrée en haute fidélité.
Comme gpt-image-2 traite toujours les images d’entrée en haute fidélité, les requêtes de modification qui incluent des images de référence peuvent consommer davantage de tokens d’image en entrée. Pour évaluer l’incidence sur le coût, consultez la section sur les coûts du traitement des images.
Exemples de tarifs des modèles antérieurs
Modèles antérieurs à gpt-image-2
Pour générer des images, les modèles GPT Image antérieurs à gpt-image-2 produisent d’abord des tokens spécialisés pour les images. La latence et le coût final sont proportionnels au nombre de tokens nécessaires au rendu. Une image plus grande ou un niveau de qualité supérieur nécessite davantage de tokens.
Le nombre de tokens générés dépend des dimensions et de la qualité de l’image.
Qualité
Carré (1024×1024)
Portrait (1024×1536)
Paysage (1536×1024)
Faible
272 tokens
408 tokens
400 tokens
Moyenne
1 056 tokens
1 584 tokens
1 568 tokens
Élevée
4 160 tokens
6 240 tokens
6 208 tokens
Tenez également compte des tokens d’entrée, qui comprennent les tokens de texte du prompt et, pour les retouches, les tokens d’image des images fournies.
Comme gpt-image-2 traite toujours les images d’entrée en haute fidélité, les requêtes de modification qui incluent des images de référence peuvent consommer davantage de tokens d’entrée.
Consultez la grille tarifaire pour connaître les tarifs actuels des tokens de texte et d’image. Utilisez la section Calcul des coûts pour estimer le coût des images en sortie.
Le coût final correspond à la somme des coûts suivants :
tokens de texte en entrée ;
tokens d’image en entrée si vous utilisez le point de terminaison de modification ;
tokens d’image en sortie.
Historique des coûts des images en sortie
gpt-image-2 accepte des milliers de résolutions. Pour faciliter la comparaison, le tableau présente les mêmes dimensions que pour les modèles GPT Image précédents. Il indique également les anciens tarifs de sortie par image pour GPT-Image-1.5, GPT-Image-1 et GPT-Image-1 Mini. Pour estimer le coût total d’une requête, tenez également compte des tokens de texte et d’image en entrée.
gpt-image-1 a été mis hors service le 23 octobre 2026. Ses tarifs figurent ci-dessous à titre de comparaison historique. Consultez l’avis de retrait pour connaître les modèles de remplacement.
À qualité égale, une image non carrée de résolution supérieure peut parfois produire moins de tokens de sortie qu’une image de résolution inférieure ou qu’une image carrée.