Skip to content

Commit 0e656d0

Browse files
committed
Add Quality and Background properties to ImageEditOptions
1 parent 2237506 commit 0e656d0

File tree

8 files changed

+121
-41
lines changed

8 files changed

+121
-41
lines changed

api/OpenAI.net8.0.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class OpenAIClientOptions : ClientPipelineOptions {
4242
public string ProjectId { get; set; }
4343
public string UserAgentApplicationId { get; set; }
4444
}
45+
[Experimental("OPENAI001")]
4546
public class OpenAIContext : ModelReaderWriterContext {
4647
public static OpenAIContext Default { get; }
4748
protected override bool TryGetTypeBuilderCore(Type type, out ModelReaderWriterTypeBuilder builder);
@@ -3405,7 +3406,11 @@ public class ImageClient {
34053406
public virtual Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null);
34063407
}
34073408
public class ImageEditOptions : IJsonModel<ImageEditOptions>, IPersistableModel<ImageEditOptions> {
3409+
[Experimental("OPENAI001")]
3410+
public GeneratedImageBackground? Background { get; set; }
34083411
public string EndUserId { get; set; }
3412+
[Experimental("OPENAI001")]
3413+
public GeneratedImageQuality? Quality { get; set; }
34093414
public GeneratedImageFormat? ResponseFormat { get; set; }
34103415
public GeneratedImageSize? Size { get; set; }
34113416
[Experimental("OPENAI001")]

api/OpenAI.netstandard2.0.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,7 +2980,9 @@ public class ImageClient {
29802980
public virtual Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null);
29812981
}
29822982
public class ImageEditOptions : IJsonModel<ImageEditOptions>, IPersistableModel<ImageEditOptions> {
2983+
public GeneratedImageBackground? Background { get; set; }
29832984
public string EndUserId { get; set; }
2985+
public GeneratedImageQuality? Quality { get; set; }
29842986
public GeneratedImageFormat? ResponseFormat { get; set; }
29852987
public GeneratedImageSize? Size { get; set; }
29862988
protected virtual ImageEditOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);

src/Custom/Images/ImageEditOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.IO;
34

45
namespace OpenAI.Images;
@@ -68,6 +69,16 @@ public partial class ImageEditOptions
6869
/// <summary> The number of images to generate. Must be between 1 and 10. </summary>
6970
internal long? N { get; set; }
7071

72+
// CUSTOM: Changed property type.
73+
[Experimental("OPENAI001")]
74+
[CodeGenMember("Background")]
75+
public GeneratedImageBackground? Background { get; set; }
76+
77+
// CUSTOM: Changed property type.
78+
[Experimental("OPENAI001")]
79+
[CodeGenMember("Quality")]
80+
public GeneratedImageQuality? Quality { get; set; }
81+
7182
// CUSTOM: Changed property type.
7283
/// <summary> The size of the generated images. Must be one of `256x256`, `512x512`, or `1024x1024`. </summary>
7384
[CodeGenMember("Size")]

src/Custom/OpenAIContext.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace OpenAI;
4+
5+
[Experimental("OPENAI001")]
6+
public partial class OpenAIContext
7+
{
8+
}

src/Generated/Models/Images/ImageEditOptions.Serialization.cs

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit
3232
{
3333
throw new FormatException($"The model {nameof(ImageEditOptions)} does not support writing '{format}' format.");
3434
}
35-
if (Optional.IsDefined(Background) && _additionalBinaryDataProperties?.ContainsKey("background") != true)
36-
{
37-
writer.WritePropertyName("background"u8);
38-
writer.WriteStringValue(Background.Value.ToString());
39-
}
40-
if (Optional.IsDefined(Quality) && _additionalBinaryDataProperties?.ContainsKey("quality") != true)
41-
{
42-
writer.WritePropertyName("quality"u8);
43-
writer.WriteStringValue(Quality.Value.ToString());
44-
}
4535
if (Optional.IsDefined(Model) && _additionalBinaryDataProperties?.ContainsKey("model") != true)
4636
{
4737
writer.WritePropertyName("model"u8);
@@ -74,6 +64,16 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit
7464
writer.WritePropertyName("n"u8);
7565
writer.WriteNumberValue(N.Value);
7666
}
67+
if (Optional.IsDefined(Background) && _additionalBinaryDataProperties?.ContainsKey("background") != true)
68+
{
69+
writer.WritePropertyName("background"u8);
70+
writer.WriteStringValue(Background.Value.ToString());
71+
}
72+
if (Optional.IsDefined(Quality) && _additionalBinaryDataProperties?.ContainsKey("quality") != true)
73+
{
74+
writer.WritePropertyName("quality"u8);
75+
writer.WriteStringValue(Quality.Value.ToString());
76+
}
7777
if (Optional.IsDefined(Size) && _additionalBinaryDataProperties?.ContainsKey("size") != true)
7878
{
7979
writer.WritePropertyName("size"u8);
@@ -131,39 +131,19 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element
131131
{
132132
return null;
133133
}
134-
InternalCreateImageEditRequestBackground? background = default;
135-
InternalCreateImageEditRequestQuality? quality = default;
136134
InternalCreateImageEditRequestModel? model = default;
137135
BinaryData image = default;
138136
string prompt = default;
139137
BinaryData mask = default;
140138
long? n = default;
139+
GeneratedImageBackground? background = default;
140+
GeneratedImageQuality? quality = default;
141141
GeneratedImageSize? size = default;
142142
GeneratedImageFormat? responseFormat = default;
143143
string endUserId = default;
144144
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
145145
foreach (var prop in element.EnumerateObject())
146146
{
147-
if (prop.NameEquals("background"u8))
148-
{
149-
if (prop.Value.ValueKind == JsonValueKind.Null)
150-
{
151-
background = null;
152-
continue;
153-
}
154-
background = new InternalCreateImageEditRequestBackground(prop.Value.GetString());
155-
continue;
156-
}
157-
if (prop.NameEquals("quality"u8))
158-
{
159-
if (prop.Value.ValueKind == JsonValueKind.Null)
160-
{
161-
quality = null;
162-
continue;
163-
}
164-
quality = new InternalCreateImageEditRequestQuality(prop.Value.GetString());
165-
continue;
166-
}
167147
if (prop.NameEquals("model"u8))
168148
{
169149
if (prop.Value.ValueKind == JsonValueKind.Null)
@@ -203,6 +183,26 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element
203183
n = prop.Value.GetInt64();
204184
continue;
205185
}
186+
if (prop.NameEquals("background"u8))
187+
{
188+
if (prop.Value.ValueKind == JsonValueKind.Null)
189+
{
190+
background = null;
191+
continue;
192+
}
193+
background = new GeneratedImageBackground(prop.Value.GetString());
194+
continue;
195+
}
196+
if (prop.NameEquals("quality"u8))
197+
{
198+
if (prop.Value.ValueKind == JsonValueKind.Null)
199+
{
200+
quality = null;
201+
continue;
202+
}
203+
quality = new GeneratedImageQuality(prop.Value.GetString());
204+
continue;
205+
}
206206
if (prop.NameEquals("size"u8))
207207
{
208208
if (prop.Value.ValueKind == JsonValueKind.Null)
@@ -232,13 +232,13 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element
232232
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
233233
}
234234
return new ImageEditOptions(
235-
background,
236-
quality,
237235
model,
238236
image,
239237
prompt,
240238
mask,
241239
n,
240+
background,
241+
quality,
242242
size,
243243
responseFormat,
244244
endUserId,

src/Generated/Models/Images/ImageEditOptions.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,21 @@ public partial class ImageEditOptions
1111
{
1212
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
1313

14-
internal ImageEditOptions(InternalCreateImageEditRequestBackground? background, InternalCreateImageEditRequestQuality? quality, InternalCreateImageEditRequestModel? model, BinaryData image, string prompt, BinaryData mask, long? n, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, IDictionary<string, BinaryData> additionalBinaryDataProperties)
14+
internal ImageEditOptions(InternalCreateImageEditRequestModel? model, BinaryData image, string prompt, BinaryData mask, long? n, GeneratedImageBackground? background, GeneratedImageQuality? quality, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, IDictionary<string, BinaryData> additionalBinaryDataProperties)
1515
{
16-
Background = background;
17-
Quality = quality;
1816
Model = model;
1917
Image = image;
2018
Prompt = prompt;
2119
Mask = mask;
2220
N = n;
21+
Background = background;
22+
Quality = quality;
2323
Size = size;
2424
ResponseFormat = responseFormat;
2525
EndUserId = endUserId;
2626
_additionalBinaryDataProperties = additionalBinaryDataProperties;
2727
}
2828

29-
internal InternalCreateImageEditRequestBackground? Background { get; set; }
30-
31-
internal InternalCreateImageEditRequestQuality? Quality { get; set; }
32-
3329
internal IDictionary<string, BinaryData> SerializedAdditionalRawData
3430
{
3531
get => _additionalBinaryDataProperties;

src/Generated/OpenAIModelFactory.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,22 @@ public static ImageInputTokenUsageDetails ImageInputTokenUsageDetails(int textTo
560560
return new ImageInputTokenUsageDetails(textTokenCount, imageTokenCount, additionalBinaryDataProperties: null);
561561
}
562562

563+
public static ImageEditOptions ImageEditOptions(InternalCreateImageEditRequestModel? model = default, BinaryData image = default, string prompt = default, BinaryData mask = default, long? n = default, GeneratedImageBackground? background = default, GeneratedImageQuality? quality = default, GeneratedImageSize? size = default, GeneratedImageFormat? responseFormat = default, string endUserId = default)
564+
{
565+
return new ImageEditOptions(
566+
model,
567+
image,
568+
prompt,
569+
mask,
570+
n,
571+
background,
572+
quality,
573+
size,
574+
responseFormat,
575+
endUserId,
576+
additionalBinaryDataProperties: null);
577+
}
578+
563579
public static ImageVariationOptions ImageVariationOptions(InternalCreateImageVariationRequestModel? model = default, BinaryData image = default, long? n = default, GeneratedImageSize? size = default, GeneratedImageFormat? responseFormat = default, string endUserId = default)
564580
{
565581
return new ImageVariationOptions(

tests/Images/ImageEditsTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,48 @@ public async Task GenerateImageEditWorks(ImageSourceKind imageSourceKind)
5858
ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal.");
5959
}
6060

61+
[Test]
62+
[TestCaseSource(nameof(s_imageSourceKindSource))]
63+
public async Task GptImage1Works(ImageSourceKind imageSourceKind)
64+
{
65+
ImageClient client = GetTestClient<ImageClient>(TestScenario.Images, "gpt-image-1");
66+
67+
string maskFilename = "images_empty_room_with_mask.png";
68+
string maskImagePath = Path.Combine("Assets", maskFilename);
69+
GeneratedImage image = null;
70+
71+
ImageEditOptions options = new()
72+
{
73+
Background = GeneratedImageBackground.Opaque,
74+
Quality = GeneratedImageQuality.Low,
75+
Size = GeneratedImageSize.W1024xH1024
76+
};
77+
78+
if (imageSourceKind == ImageSourceKind.UsingStream)
79+
{
80+
using FileStream mask = File.OpenRead(maskImagePath);
81+
82+
image = IsAsync
83+
? await client.GenerateImageEditAsync(mask, maskFilename, CatPrompt, options)
84+
: client.GenerateImageEdit(mask, maskFilename, CatPrompt, options);
85+
}
86+
else if (imageSourceKind == ImageSourceKind.UsingFilePath)
87+
{
88+
image = IsAsync
89+
? await client.GenerateImageEditAsync(maskImagePath, CatPrompt, options)
90+
: client.GenerateImageEdit(maskImagePath, CatPrompt, options);
91+
}
92+
else
93+
{
94+
Assert.Fail("Invalid source kind.");
95+
}
96+
97+
Assert.That(image.ImageUri, Is.Null);
98+
Assert.That(image.ImageBytes, Is.Not.Null);
99+
100+
ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal.");
101+
}
102+
61103
[Test]
62104
[TestCaseSource(nameof(s_imageSourceKindSource))]
63105
public async Task GenerateImageEditWithBytesResponseWorks(ImageSourceKind imageSourceKind)

0 commit comments

Comments
 (0)