openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.1.0-beta.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Custom/Images/ImageClient.cs

841lines · modecode

1using System;
2using System.ClientModel;
3using System.ClientModel.Primitives;
4using System.IO;
5using System.Linq;
6using System.Threading;
7using System.Threading.Tasks;
8
9namespace OpenAI.Images;
10
11// CUSTOM:
12// - Renamed.
13// - Suppressed constructor that takes endpoint parameter; endpoint is now a property in the options class.
14// - Suppressed methods that only take the options parameter.
15/// <summary> The service client for OpenAI image operations. </summary>
16[CodeGenClient("Images")]
17[CodeGenSuppress("ImageClient", typeof(ClientPipeline), typeof(ApiKeyCredential), typeof(Uri))]
18[CodeGenSuppress("CreateImageAsync", typeof(ImageGenerationOptions))]
19[CodeGenSuppress("CreateImage", typeof(ImageGenerationOptions))]
20[CodeGenSuppress("CreateImageEditAsync", typeof(ImageEditOptions))]
21[CodeGenSuppress("CreateImageEdit", typeof(ImageEditOptions))]
22[CodeGenSuppress("CreateImageVariationAsync", typeof(ImageVariationOptions))]
23[CodeGenSuppress("CreateImageVariation", typeof(ImageVariationOptions))]
24public partial class ImageClient
25{
26 private readonly string _model;
27
28 // CUSTOM: Remove virtual keyword.
29 /// <summary>
30 /// The HTTP pipeline for sending and receiving REST requests and responses.
31 /// </summary>
32 public ClientPipeline Pipeline => _pipeline;
33
34 // CUSTOM: Added as a convenience.
35 /// <summary> Initializes a new instance of <see cref="ImageClient">. </summary>
36 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
37 /// <param name="apiKey"> The API key to authenticate with the service. </param>
38 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="apiKey"/> is null. </exception>
39 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
40 public ImageClient(string model, string apiKey) : this(model, new ApiKeyCredential(apiKey), new OpenAIClientOptions())
41 {
42 }
43
44 // CUSTOM:
45 // - Added `model` parameter.
46 // - Used a custom pipeline.
47 // - Demoted the endpoint parameter to be a property in the options class.
48 /// <summary> Initializes a new instance of <see cref="ImageClient">. </summary>
49 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
50 /// <param name="credential"> The API key to authenticate with the service. </param>
51 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="credential"/> is null. </exception>
52 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
53 public ImageClient(string model, ApiKeyCredential credential) : this(model, credential, new OpenAIClientOptions())
54 {
55 }
56
57 // CUSTOM:
58 // - Added `model` parameter.
59 // - Used a custom pipeline.
60 // - Demoted the endpoint parameter to be a property in the options class.
61 /// <summary> Initializes a new instance of <see cref="ImageClient">. </summary>
62 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
63 /// <param name="credential"> The API key to authenticate with the service. </param>
64 /// <param name="options"> The options to configure the client. </param>
65 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="credential"/> is null. </exception>
66 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
67 public ImageClient(string model, ApiKeyCredential credential, OpenAIClientOptions options)
68 {
69 Argument.AssertNotNullOrEmpty(model, nameof(model));
70 Argument.AssertNotNull(credential, nameof(credential));
71 options ??= new OpenAIClientOptions();
72
73 _model = model;
74 _pipeline = OpenAIClient.CreatePipeline(credential, options);
75 _endpoint = OpenAIClient.GetEndpoint(options);
76 }
77
78 // CUSTOM:
79 // - Added `model` parameter.
80 // - Used a custom pipeline.
81 // - Demoted the endpoint parameter to be a property in the options class.
82 // - Made protected.
83 /// <summary> Initializes a new instance of <see cref="ImageClient">. </summary>
84 /// <param name="pipeline"> The HTTP pipeline to send and receive REST requests and responses. </param>
85 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
86 /// <param name="options"> The options to configure the client. </param>
87 /// <exception cref="ArgumentNullException"> <paramref name="pipeline"/> or <paramref name="model"/> is null. </exception>
88 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
89 protected internal ImageClient(ClientPipeline pipeline, string model, OpenAIClientOptions options)
90 {
91 Argument.AssertNotNull(pipeline, nameof(pipeline));
92 Argument.AssertNotNullOrEmpty(model, nameof(model));
93 options ??= new OpenAIClientOptions();
94
95 _model = model;
96 _pipeline = pipeline;
97 _endpoint = OpenAIClient.GetEndpoint(options);
98 }
99
100 #region GenerateImages
101
102 /// <summary> Generates an image based on a prompt. </summary>
103 /// <param name="prompt"> A text description of the desired image. </param>
104 /// <param name="options"> The options to configure the image generation. </param>
105 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
106 /// <exception cref="ArgumentNullException"> <paramref name="prompt"/> is null. </exception>
107 /// <exception cref="ArgumentException"> <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
108 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageAsync(string prompt, ImageGenerationOptions options = null, CancellationToken cancellationToken = default)
109 {
110 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
111
112 options ??= new();
113 CreateImageGenerationOptions(prompt, null, ref options);
114
115 using BinaryContent content = options.ToBinaryContent();
116 ClientResult result = await GenerateImagesAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
117 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
118 }
119
120 /// <summary> Generates an image based on a prompt. </summary>
121 /// <param name="prompt"> A text description of the desired image. </param>
122 /// <param name="options"> The options to configure the image generation. </param>
123 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
124 /// <exception cref="ArgumentNullException"> <paramref name="prompt"/> is null. </exception>
125 /// <exception cref="ArgumentException"> <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
126 public virtual ClientResult<GeneratedImage> GenerateImage(string prompt, ImageGenerationOptions options = null, CancellationToken cancellationToken = default)
127 {
128 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
129
130 options ??= new();
131 CreateImageGenerationOptions(prompt, null, ref options);
132
133 using BinaryContent content = options.ToBinaryContent();
134 ClientResult result = GenerateImages(content, cancellationToken.ToRequestOptions());
135 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
136 }
137
138 /// <summary> Generates images based on a prompt. </summary>
139 /// <param name="prompt"> A text description of the desired images. </param>
140 /// <param name="imageCount"> The number of images to generate. </param>
141 /// <param name="options"> The options to configure the image generation. </param>
142 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
143 /// <exception cref="ArgumentNullException"> <paramref name="prompt"/> is null. </exception>
144 /// <exception cref="ArgumentException"> <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
145 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImagesAsync(string prompt, int imageCount, ImageGenerationOptions options = null, CancellationToken cancellationToken = default)
146 {
147 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
148
149 options ??= new();
150 CreateImageGenerationOptions(prompt, imageCount, ref options);
151
152 using BinaryContent content = options.ToBinaryContent();
153 ClientResult result = await GenerateImagesAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
154 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
155 }
156
157 /// <summary> Generates images based on a prompt. </summary>
158 /// <param name="prompt"> A text description of the desired images. </param>
159 /// <param name="imageCount"> The number of images to generate. </param>
160 /// <param name="options"> The options to configure the image generation. </param>
161 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
162 /// <exception cref="ArgumentNullException"> <paramref name="prompt"/> is null. </exception>
163 /// <exception cref="ArgumentException"> <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
164 public virtual ClientResult<GeneratedImageCollection> GenerateImages(string prompt, int imageCount, ImageGenerationOptions options = null, CancellationToken cancellationToken = default)
165 {
166 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
167
168 options ??= new();
169 CreateImageGenerationOptions(prompt, imageCount, ref options);
170
171 using BinaryContent content = options.ToBinaryContent();
172 ClientResult result = GenerateImages(content, cancellationToken.ToRequestOptions());
173 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
174 }
175
176 #endregion
177
178 #region GenerateImageEdits
179
180 /// <summary> Generates an edited or extended image based on an original image and a prompt. </summary>
181 /// <param name="image">
182 /// The image stream to edit. Must be a valid PNG file, less than 4MB, and square. The image must have transparency, which
183 /// will be used as the mask.
184 /// </param>
185 /// <param name="imageFilename">
186 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
187 /// validate the format of the input image. The request may fail if the filename's extension and the actual
188 /// format of the input image do not match.
189 /// </param>
190 /// <param name="prompt"> A text description of the desired image. </param>
191 /// <param name="options"> The options to configure the image edit. </param>
192 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
193 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, or <paramref name="prompt"/> is null. </exception>
194 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
195 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageEditAsync(Stream image, string imageFilename, string prompt, ImageEditOptions options = null, CancellationToken cancellationToken = default)
196 {
197 Argument.AssertNotNull(image, nameof(image));
198 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
199 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
200
201 options ??= new();
202 CreateImageEditOptions(image, imageFilename, prompt, null, null, null, ref options);
203
204 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, null, null);
205 ClientResult result = await GenerateImageEditsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
206 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
207 }
208
209 /// <summary> Generates an edited or extended image based on an original image and a prompt. </summary>
210 /// <param name="image">
211 /// The image stream to edit. Must be a valid PNG file, less than 4MB, and square. The image must have transparency, which
212 /// will be used as the mask.
213 /// </param>
214 /// <param name="imageFilename">
215 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
216 /// validate the format of the input image. The request may fail if the filename's extension and the actual
217 /// format of the input image do not match.
218 /// </param>
219 /// <param name="prompt"> A text description of the desired image. </param>
220 /// <param name="options"> The options to configure the image edit. </param>
221 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
222 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, or <paramref name="prompt"/> is null. </exception>
223 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
224 public virtual ClientResult<GeneratedImage> GenerateImageEdit(Stream image, string imageFilename, string prompt, ImageEditOptions options = null, CancellationToken cancellationToken = default)
225 {
226 Argument.AssertNotNull(image, nameof(image));
227 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
228 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
229
230 options ??= new();
231 CreateImageEditOptions(image, imageFilename, prompt, null, null, null, ref options);
232
233 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, null, null);
234 ClientResult result = GenerateImageEdits(content, content.ContentType, cancellationToken.ToRequestOptions());
235 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
236 }
237
238 /// <summary> Generates an edited or extended image based on an original image and a prompt. </summary>
239 /// <param name="imageFilePath">
240 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The image must
241 /// have transparency, which will be used as the mask. The provided file path's extension (for example: .png)
242 /// will be used to validate the format of the input image. The request may fail if the file path's extension
243 /// and the actual format of the input image do not match.
244 /// </param>
245 /// <param name="prompt"> A text description of the desired image. </param>
246 /// <param name="options"> The options to configure the image edit. </param>
247 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is null. </exception>
248 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
249 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageEditAsync(string imageFilePath, string prompt, ImageEditOptions options = null)
250 {
251 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
252 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
253
254 using FileStream imageStream = File.OpenRead(imageFilePath);
255 return await GenerateImageEditAsync(imageStream, imageFilePath, prompt, options).ConfigureAwait(false);
256 }
257
258 /// <summary> Generates an edited or extended image based on an original image and a prompt. </summary>
259 /// <param name="imageFilePath">
260 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The image must
261 /// have transparency, which will be used as the mask. The provided file path's extension (for example: .png)
262 /// will be used to validate the format of the input image. The request may fail if the file path's extension
263 /// and the actual format of the input image do not match.
264 /// </param>
265 /// <param name="prompt"> A text description of the desired image. </param>
266 /// <param name="options"> The options to configure the image edit. </param>
267 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is null. </exception>
268 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
269 public virtual ClientResult<GeneratedImage> GenerateImageEdit(string imageFilePath, string prompt, ImageEditOptions options = null)
270 {
271 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
272 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
273
274 using FileStream imageStream = File.OpenRead(imageFilePath);
275 return GenerateImageEdit(imageStream, imageFilePath, prompt, options);
276 }
277
278 /// <summary> Generates an edited or extended image based on an original image, a prompt, and a mask. </summary>
279 /// <param name="image"> The image stream to edit. Must be a valid PNG file, less than 4MB, and square. </param>
280 /// <param name="imageFilename">
281 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
282 /// validate the format of the input image. The request may fail if the filename's extension and the actual
283 /// format of the input image do not match.
284 /// </param>
285 /// <param name="prompt"> A text description of the desired image. </param>
286 /// <param name="mask">
287 /// An additional image whose fully transparent areas (i.e., where alpha is zero) indicate where the original image
288 /// should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
289 /// </param>
290 /// <param name="maskFilename">
291 /// The filename associated with the mask image stream. The filename's extension (for example: .png) will be
292 /// used to validate the format of the mask image. The request may fail if the filename's extension and the
293 /// actual format of the mask image do not match.
294 /// </param>
295 /// <param name="options"> The options to configure the image edit. </param>
296 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
297 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, <paramref name="prompt"/>, <paramref name="mask"/>, or <paramref name="maskFilename"/> is null. </exception>
298 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/>, <paramref name="prompt"/>, or <paramref name="maskFilename"/> is an empty string, and was expected to be non-empty. </exception>
299 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageEditAsync(Stream image, string imageFilename, string prompt, Stream mask, string maskFilename, ImageEditOptions options = null, CancellationToken cancellationToken = default)
300 {
301 Argument.AssertNotNull(image, nameof(image));
302 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
303 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
304 Argument.AssertNotNull(mask, nameof(mask));
305 Argument.AssertNotNullOrEmpty(maskFilename, nameof(maskFilename));
306
307 options ??= new();
308 CreateImageEditOptions(image, imageFilename, prompt, mask, maskFilename, null, ref options);
309
310 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, mask, maskFilename);
311 ClientResult result = await GenerateImageEditsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
312 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
313 }
314
315 /// <summary> Generates an edited or extended image based on an original image, a prompt, and a mask. </summary>
316 /// <param name="image"> The image stream to edit. Must be a valid PNG file, less than 4MB, and square. </param>
317 /// <param name="imageFilename">
318 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
319 /// validate the format of the input image. The request may fail if the filename's extension and the actual
320 /// format of the input image do not match.
321 /// </param>
322 /// <param name="prompt"> A text description of the desired image. </param>
323 /// <param name="mask">
324 /// An additional image whose fully transparent areas (i.e., where alpha is zero) indicate where the original image
325 /// should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
326 /// </param>
327 /// <param name="maskFilename">
328 /// The filename associated with the mask image stream. The filename's extension (for example: .png) will be
329 /// used to validate the format of the mask image. The request may fail if the filename's extension and the
330 /// actual format of the mask image do not match.
331 /// </param>
332 /// <param name="options"> The options to configure the image edit. </param>
333 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
334 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, <paramref name="prompt"/>, <paramref name="mask"/>, or <paramref name="maskFilename"/> is null. </exception>
335 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/>, <paramref name="prompt"/>, or <paramref name="maskFilename"/> is an empty string, and was expected to be non-empty. </exception>
336 public virtual ClientResult<GeneratedImage> GenerateImageEdit(Stream image, string imageFilename, string prompt, Stream mask, string maskFilename, ImageEditOptions options = null, CancellationToken cancellationToken = default)
337 {
338 Argument.AssertNotNull(image, nameof(image));
339 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
340 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
341 Argument.AssertNotNull(mask, nameof(mask));
342 Argument.AssertNotNullOrEmpty(maskFilename, nameof(maskFilename));
343
344 options ??= new();
345 CreateImageEditOptions(image, imageFilename, prompt, mask, maskFilename, null, ref options);
346
347 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, mask, maskFilename);
348 ClientResult result = GenerateImageEdits(content, content.ContentType, cancellationToken.ToRequestOptions());
349 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
350 }
351
352 /// <summary> Generates an edited or extended image based on an original image, a prompt, and a mask. </summary>
353 /// <param name="imageFilePath">
354 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The provided file
355 /// path's extension (for example: .png) will be used to validate the format of the input image. The request
356 /// may fail if the file path's extension and the actual format of the input image do not match.
357 /// </param>
358 /// <param name="prompt"> A text description of the desired image. </param>
359 /// <param name="maskFilePath">
360 /// The path of the mask image file whose fully transparent areas (i.e., where alpha is zero) indicate where
361 /// the original image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions
362 /// as the original image. The provided file path's extension (for example: .png) will be used to validate the
363 /// format of the mask image. The request may fail if the file path's extension and the actual format of the
364 /// mask image do not match.
365 /// </param>
366 /// <param name="options"> The options to configure the image edit. </param>
367 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/> or <paramref name="maskFilePath"/> is null. </exception>
368 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/>, or <paramref name="maskFilePath"/> is an empty string, and was expected to be non-empty. </exception>
369 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageEditAsync(string imageFilePath, string prompt, string maskFilePath, ImageEditOptions options = null)
370 {
371 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
372 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
373 Argument.AssertNotNullOrEmpty(maskFilePath, nameof(maskFilePath));
374
375 using FileStream imageStream = File.OpenRead(imageFilePath);
376 using FileStream maskStream = File.OpenRead(maskFilePath);
377 return await GenerateImageEditAsync(imageStream, imageFilePath, prompt, maskStream, maskFilePath, options).ConfigureAwait(false);
378 }
379
380 /// <summary> Generates an edited or extended image based on an original image, a prompt, and a mask. </summary>
381 /// <param name="imageFilePath">
382 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The provided file
383 /// path's extension (for example: .png) will be used to validate the format of the input image. The request
384 /// may fail if the file path's extension and the actual format of the input image do not match.
385 /// </param>
386 /// <param name="prompt"> A text description of the desired image. </param>
387 /// <param name="maskFilePath">
388 /// The path of the mask image file whose fully transparent areas (i.e., where alpha is zero) indicate where
389 /// the original image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions
390 /// as the original image. The provided file path's extension (for example: .png) will be used to validate the
391 /// format of the mask image. The request may fail if the file path's extension and the actual format of the
392 /// mask image do not match.
393 /// </param>
394 /// <param name="options"> The options to configure the image edit. </param>
395 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/> or <paramref name="maskFilePath"/> is null. </exception>
396 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/>, or <paramref name="maskFilePath"/> is an empty string, and was expected to be non-empty. </exception>
397 public virtual ClientResult<GeneratedImage> GenerateImageEdit(string imageFilePath, string prompt, string maskFilePath, ImageEditOptions options = null)
398 {
399 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
400 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
401 Argument.AssertNotNullOrEmpty(maskFilePath, nameof(maskFilePath));
402
403 using FileStream imageStream = File.OpenRead(imageFilePath);
404 using FileStream maskStream = File.OpenRead(maskFilePath);
405 return GenerateImageEdit(imageStream, imageFilePath, prompt, maskStream, maskFilePath, options);
406 }
407
408 /// <summary> Generates edited or extended images based on an original image and a prompt. </summary>
409 /// <param name="image">
410 /// The image stream to edit. Must be a valid PNG file, less than 4MB, and square. The image must have transparency, which
411 /// will be used as the mask.
412 /// </param>
413 /// <param name="imageFilename">
414 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
415 /// validate the format of the input image. The request may fail if the filename's extension and the actual
416 /// format of the input image do not match.
417 /// </param>
418 /// <param name="prompt"> A text description of the desired image. </param>
419 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
420 /// <param name="options"> The options to configure the image edit. </param>
421 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
422 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, or <paramref name="prompt"/> is null. </exception>
423 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
424 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageEditsAsync(Stream image, string imageFilename, string prompt, int imageCount, ImageEditOptions options = null, CancellationToken cancellationToken = default)
425 {
426 Argument.AssertNotNull(image, nameof(image));
427 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
428 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
429
430 options ??= new();
431 CreateImageEditOptions(image, imageFilename, prompt, null, null, imageCount, ref options);
432
433 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, null, null);
434 ClientResult result = await GenerateImageEditsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
435 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
436 }
437
438 /// <summary> Generates edited or extended images based on an original image and a prompt. </summary>
439 /// <param name="image">
440 /// The image stream to edit. Must be a valid PNG file, less than 4MB, and square. The image must have transparency, which
441 /// will be used as the mask.
442 /// </param>
443 /// <param name="imageFilename">
444 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
445 /// validate the format of the input image. The request may fail if the filename's extension and the actual
446 /// format of the input image do not match.
447 /// </param>
448 /// <param name="prompt"> A text description of the desired image. </param>
449 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
450 /// <param name="options"> The options to configure the image edit. </param>
451 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
452 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, or <paramref name="prompt"/> is null. </exception>
453 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
454 public virtual ClientResult<GeneratedImageCollection> GenerateImageEdits(Stream image, string imageFilename, string prompt, int imageCount, ImageEditOptions options = null, CancellationToken cancellationToken = default)
455 {
456 Argument.AssertNotNull(image, nameof(image));
457 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
458 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
459
460 options ??= new();
461 CreateImageEditOptions(image, imageFilename, prompt, null, null, imageCount, ref options);
462
463 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, null, null);
464 ClientResult result = GenerateImageEdits(content, content.ContentType, cancellationToken.ToRequestOptions());
465 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
466 }
467
468 /// <summary> Generates edited or extended images based on an original image and a prompt. </summary>
469 /// <param name="imageFilePath">
470 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The image must
471 /// have transparency, which will be used as the mask. The provided file path's extension (for example: .png)
472 /// will be used to validate the format of the input image. The request may fail if the file path's extension
473 /// and the actual format of the input image do not match.
474 /// </param>
475 /// <param name="prompt"> A text description of the desired image. </param>
476 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
477 /// <param name="options"> The options to configure the image edit. </param>
478 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is null. </exception>
479 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
480 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageEditsAsync(string imageFilePath, string prompt, int imageCount, ImageEditOptions options = null)
481 {
482 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
483 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
484
485 using FileStream imageStream = File.OpenRead(imageFilePath);
486 return await GenerateImageEditsAsync(imageStream, imageFilePath, prompt, imageCount, options).ConfigureAwait(false);
487 }
488
489 /// <summary> Generates edited or extended images based on an original image and a prompt. </summary>
490 /// <param name="imageFilePath">
491 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The image must
492 /// have transparency, which will be used as the mask. The provided file path's extension (for example: .png)
493 /// will be used to validate the format of the input image. The request may fail if the file path's extension
494 /// and the actual format of the input image do not match.
495 /// </param>
496 /// <param name="prompt"> A text description of the desired image. </param>
497 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
498 /// <param name="options"> The options to configure the image edit. </param>
499 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is null. </exception>
500 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> or <paramref name="prompt"/> is an empty string, and was expected to be non-empty. </exception>
501 public virtual ClientResult<GeneratedImageCollection> GenerateImageEdits(string imageFilePath, string prompt, int imageCount, ImageEditOptions options = null)
502 {
503 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
504 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
505
506 using FileStream imageStream = File.OpenRead(imageFilePath);
507 return GenerateImageEdits(imageStream, imageFilePath, prompt, imageCount, options);
508 }
509
510 /// <summary> Generates edited or extended images based on an original image, a prompt, and a mask. </summary>
511 /// <param name="image"> The image stream to edit. Must be a valid PNG file, less than 4MB, and square. </param>
512 /// <param name="imageFilename">
513 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
514 /// validate the format of the input image. The request may fail if the filename's extension and the actual
515 /// format of the input image do not match.
516 /// </param>
517 /// <param name="prompt"> A text description of the desired image. </param>
518 /// <param name="mask">
519 /// An additional image whose fully transparent areas (i.e., where alpha is zero) indicate where the original image
520 /// should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
521 /// </param>
522 /// <param name="maskFilename">
523 /// The filename associated with the mask image stream. The filename's extension (for example: .png) will be
524 /// used to validate the format of the mask image. The request may fail if the filename's extension and the
525 /// actual format of the mask image do not match.
526 /// </param>
527 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
528 /// <param name="options"> The options to configure the image edit. </param>
529 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
530 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, <paramref name="prompt"/>, <paramref name="mask"/>, or <paramref name="maskFilename"/> is null. </exception>
531 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/>, <paramref name="prompt"/>, or <paramref name="maskFilename"/> is an empty string, and was expected to be non-empty. </exception>
532 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageEditsAsync(Stream image, string imageFilename, string prompt, Stream mask, string maskFilename, int imageCount, ImageEditOptions options = null, CancellationToken cancellationToken = default)
533 {
534 Argument.AssertNotNull(image, nameof(image));
535 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
536 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
537 Argument.AssertNotNull(mask, nameof(mask));
538 Argument.AssertNotNullOrEmpty(maskFilename, nameof(maskFilename));
539
540 options ??= new();
541 CreateImageEditOptions(image, imageFilename, prompt, mask, maskFilename, imageCount, ref options);
542
543 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, mask, maskFilename);
544 ClientResult result = await GenerateImageEditsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
545 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
546 }
547
548 /// <summary> Generates edited or extended images based on an original image, a prompt, and a mask. </summary>
549 /// <param name="image"> The image stream to edit. Must be a valid PNG file, less than 4MB, and square. </param>
550 /// <param name="imageFilename">
551 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
552 /// validate the format of the input image. The request may fail if the filename's extension and the actual
553 /// format of the input image do not match.
554 /// </param>
555 /// <param name="prompt"> A text description of the desired image. </param>
556 /// <param name="mask">
557 /// An additional image whose fully transparent areas (i.e., where alpha is zero) indicate where the original image
558 /// should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
559 /// </param>
560 /// <param name="maskFilename">
561 /// The filename associated with the mask image stream. The filename's extension (for example: .png) will be
562 /// used to validate the format of the mask image. The request may fail if the filename's extension and the
563 /// actual format of the mask image do not match.
564 /// </param>
565 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
566 /// <param name="options"> The options to configure the image edit. </param>
567 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
568 /// <exception cref="ArgumentNullException"> <paramref name="image"/>, <paramref name="imageFilename"/>, <paramref name="prompt"/>, <paramref name="mask"/>, or <paramref name="maskFilename"/> is null. </exception>
569 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/>, <paramref name="prompt"/>, or <paramref name="maskFilename"/> is an empty string, and was expected to be non-empty. </exception>
570 public virtual ClientResult<GeneratedImageCollection> GenerateImageEdits(Stream image, string imageFilename, string prompt, Stream mask, string maskFilename, int imageCount, ImageEditOptions options = null, CancellationToken cancellationToken = default)
571 {
572 Argument.AssertNotNull(image, nameof(image));
573 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
574 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
575 Argument.AssertNotNull(mask, nameof(mask));
576 Argument.AssertNotNullOrEmpty(maskFilename, nameof(maskFilename));
577
578 options ??= new();
579 CreateImageEditOptions(image, imageFilename, prompt, mask, maskFilename, imageCount, ref options);
580
581 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename, mask, maskFilename);
582 ClientResult result = GenerateImageEdits(content, content.ContentType, cancellationToken.ToRequestOptions());
583 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
584 }
585
586 /// <summary> Generates edited or extended images based on an original image, a prompt, and a mask. </summary>
587 /// <param name="imageFilePath">
588 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The provided file
589 /// path's extension (for example: .png) will be used to validate the format of the input image. The request
590 /// may fail if the file path's extension and the actual format of the input image do not match.
591 /// </param>
592 /// <param name="prompt"> A text description of the desired image. </param>
593 /// <param name="maskFilePath">
594 /// The path of the mask image file whose fully transparent areas (i.e., where alpha is zero) indicate where
595 /// the original image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions
596 /// as the original image. The provided file path's extension (for example: .png) will be used to validate the
597 /// format of the mask image. The request may fail if the file path's extension and the actual format of the
598 /// mask image do not match.
599 /// </param>
600 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
601 /// <param name="options"> The options to configure the image edit. </param>
602 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/> or <paramref name="maskFilePath"/> is null. </exception>
603 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/>, or <paramref name="maskFilePath"/> is an empty string, and was expected to be non-empty. </exception>
604 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageEditsAsync(string imageFilePath, string prompt, string maskFilePath, int imageCount, ImageEditOptions options = null)
605 {
606 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
607 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
608 Argument.AssertNotNullOrEmpty(maskFilePath, nameof(maskFilePath));
609
610 using FileStream imageStream = File.OpenRead(imageFilePath);
611 using FileStream maskStream = File.OpenRead(maskFilePath);
612 return await GenerateImageEditsAsync(imageStream, imageFilePath, prompt, maskStream, maskFilePath, imageCount, options).ConfigureAwait(false);
613 }
614
615 /// <summary> Generates edited or extended images based on an original image, a prompt, and a mask. </summary>
616 /// <param name="imageFilePath">
617 /// The path of the image file to edit. Must be a valid PNG file, less than 4MB, and square. The provided file
618 /// path's extension (for example: .png) will be used to validate the format of the input image. The request
619 /// may fail if the file path's extension and the actual format of the input image do not match.
620 /// </param>
621 /// <param name="prompt"> A text description of the desired image. </param>
622 /// <param name="maskFilePath">
623 /// The path of the mask image file whose fully transparent areas (i.e., where alpha is zero) indicate where
624 /// the original image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions
625 /// as the original image. The provided file path's extension (for example: .png) will be used to validate the
626 /// format of the mask image. The request may fail if the file path's extension and the actual format of the
627 /// mask image do not match.
628 /// </param>
629 /// <param name="imageCount"> The number of edited or extended images to generate. </param>
630 /// <param name="options"> The options to configure the image edit. </param>
631 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/> or <paramref name="maskFilePath"/> is null. </exception>
632 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/>, <paramref name="prompt"/>, or <paramref name="maskFilePath"/> is an empty string, and was expected to be non-empty. </exception>
633 public virtual ClientResult<GeneratedImageCollection> GenerateImageEdits(string imageFilePath, string prompt, string maskFilePath, int imageCount, ImageEditOptions options = null)
634 {
635 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
636 Argument.AssertNotNullOrEmpty(prompt, nameof(prompt));
637 Argument.AssertNotNullOrEmpty(maskFilePath, nameof(maskFilePath));
638
639 using FileStream imageStream = File.OpenRead(imageFilePath);
640 using FileStream maskStream = File.OpenRead(maskFilePath);
641 return GenerateImageEdits(imageStream, imageFilePath, prompt, maskStream, maskFilePath, imageCount, options);
642 }
643
644 #endregion
645
646 #region GenerateImageVariations
647
648 /// <summary> Generates a variation of a given image. </summary>
649 /// <param name="image"> The image stream to use as the basis for the variation. Must be a valid PNG file, less than 4MB, and square. </param>
650 /// <param name="imageFilename">
651 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
652 /// validate the format of the input image. The request may fail if the filename's extension and the actual
653 /// format of the input image do not match.
654 /// </param>
655 /// <param name="options"> The options to configure the image variation. </param>
656 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
657 /// <exception cref="ArgumentNullException"> <paramref name="image"/> or <paramref name="imageFilename"/> is null. </exception>
658 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> is an empty string, and was expected to be non-empty. </exception>
659 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageVariationAsync(Stream image, string imageFilename, ImageVariationOptions options = null, CancellationToken cancellationToken = default)
660 {
661 Argument.AssertNotNull(image, nameof(image));
662 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
663
664 options ??= new();
665 CreateImageVariationOptions(image, imageFilename, null, ref options);
666
667 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename);
668 ClientResult result = await GenerateImageVariationsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
669 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
670 }
671
672 /// <summary> Generates a variation of a given image. </summary>
673 /// <param name="image"> The image stream to use as the basis for the variation. Must be a valid PNG file, less than 4MB, and square. </param>
674 /// <param name="imageFilename">
675 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
676 /// validate the format of the input image. The request may fail if the filename's extension and the actual
677 /// format of the input image do not match.
678 /// </param>
679 /// <param name="options"> The options to configure the image variation. </param>
680 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
681 /// <exception cref="ArgumentNullException"> <paramref name="image"/> or <paramref name="imageFilename"/> is null. </exception>
682 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> is an empty string, and was expected to be non-empty. </exception>
683 public virtual ClientResult<GeneratedImage> GenerateImageVariation(Stream image, string imageFilename, ImageVariationOptions options = null, CancellationToken cancellationToken = default)
684 {
685 Argument.AssertNotNull(image, nameof(image));
686 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
687
688 options ??= new();
689 CreateImageVariationOptions(image, imageFilename, null, ref options);
690
691 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename);
692 ClientResult result = GenerateImageVariations(content, content.ContentType, cancellationToken.ToRequestOptions());
693 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()).FirstOrDefault(), result.GetRawResponse());
694 }
695
696 /// <summary> Generates a variation of a given image. </summary>
697 /// <param name="imageFilePath">
698 /// The path of the image file to use as the basis for the variation. Must be a valid PNG file, less than 4MB,
699 /// and square. The provided file path's extension (for example: .png) will be used to validate the format of
700 /// the input image. The request may fail if the file path's extension and the actual format of the input image
701 /// do not match.
702 /// </param>
703 /// <param name="options"> The options to configure the image variation. </param>
704 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> is null. </exception>
705 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> is an empty string, and was expected to be non-empty. </exception>
706 public virtual async Task<ClientResult<GeneratedImage>> GenerateImageVariationAsync(string imageFilePath, ImageVariationOptions options = null)
707 {
708 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
709
710 using FileStream imageStream = File.OpenRead(imageFilePath);
711 return await GenerateImageVariationAsync(imageStream, imageFilePath, options).ConfigureAwait(false);
712 }
713
714 /// <summary> Generates a variation of a given image. </summary>
715 /// <param name="imageFilePath">
716 /// The path of the image file to use as the basis for the variation. Must be a valid PNG file, less than 4MB,
717 /// and square. The provided file path's extension (for example: .png) will be used to validate the format of
718 /// the input image. The request may fail if the file path's extension and the actual format of the input image
719 /// do not match.
720 /// </param>
721 /// <param name="options"> The options to configure the image variation. </param>
722 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> is null. </exception>
723 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> is an empty string, and was expected to be non-empty. </exception>
724 public virtual ClientResult<GeneratedImage> GenerateImageVariation(string imageFilePath, ImageVariationOptions options = null)
725 {
726 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
727
728 using FileStream imageStream = File.OpenRead(imageFilePath);
729 return GenerateImageVariation(imageStream, imageFilePath, options);
730 }
731
732 /// <summary> Generates variations of a given image. </summary>
733 /// <param name="image"> The image stream to use as the basis for the variation. Must be a valid PNG file, less than 4MB, and square. </param>
734 /// <param name="imageFilename">
735 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
736 /// validate the format of the input image. The request may fail if the filename's extension and the actual
737 /// format of the input image do not match.
738 /// </param>
739 /// <param name="imageCount"> The number of image variations to generate. </param>
740 /// <param name="options"> The options to configure the image variation. </param>
741 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
742 /// <exception cref="ArgumentNullException"> <paramref name="image"/> or <paramref name="imageFilename"/> is null. </exception>
743 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> is an empty string, and was expected to be non-empty. </exception>
744 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(Stream image, string imageFilename, int imageCount, ImageVariationOptions options = null, CancellationToken cancellationToken = default)
745 {
746 Argument.AssertNotNull(image, nameof(image));
747 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
748
749 options ??= new();
750 CreateImageVariationOptions(image, imageFilename, imageCount, ref options);
751
752 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename);
753 ClientResult result = await GenerateImageVariationsAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
754 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
755 }
756
757 /// <summary> Generates variations of a given image. </summary>
758 /// <param name="image"> The image stream to use as the basis for the variation. Must be a valid PNG file, less than 4MB, and square. </param>
759 /// <param name="imageFilename">
760 /// The filename associated with the image stream. The filename's extension (for example: .png) will be used to
761 /// validate the format of the input image. The request may fail if the filename's extension and the actual
762 /// format of the input image do not match.
763 /// </param>
764 /// <param name="imageCount"> The number of image variations to generate. </param>
765 /// <param name="options"> The options to configure the image variation. </param>
766 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
767 /// <exception cref="ArgumentNullException"> <paramref name="image"/> or <paramref name="imageFilename"/> is null. </exception>
768 /// <exception cref="ArgumentException"> <paramref name="imageFilename"/> is an empty string, and was expected to be non-empty. </exception>
769 public virtual ClientResult<GeneratedImageCollection> GenerateImageVariations(Stream image, string imageFilename, int imageCount, ImageVariationOptions options = null, CancellationToken cancellationToken = default)
770 {
771 Argument.AssertNotNull(image, nameof(image));
772 Argument.AssertNotNullOrEmpty(imageFilename, nameof(imageFilename));
773
774 options ??= new();
775 CreateImageVariationOptions(image, imageFilename, imageCount, ref options);
776
777 using MultipartFormDataBinaryContent content = options.ToMultipartContent(image, imageFilename);
778 ClientResult result = GenerateImageVariations(content, content.ContentType, cancellationToken.ToRequestOptions());
779 return ClientResult.FromValue(GeneratedImageCollection.FromResponse(result.GetRawResponse()), result.GetRawResponse());
780 }
781
782 /// <summary> Generates variations of a given image. </summary>
783 /// <param name="imageFilePath">
784 /// The path of the image file to use as the basis for the variation. Must be a valid PNG file, less than 4MB,
785 /// and square. The provided file path's extension (for example: .png) will be used to validate the format of
786 /// the input image. The request may fail if the file path's extension and the actual format of the input image
787 /// do not match.
788 /// </param>
789 /// <param name="imageCount"> The number of image variations to generate. </param>
790 /// <param name="options"> The options to configure the image variation. </param>
791 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> was null. </exception>
792 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> is an empty string, and was expected to be non-empty. </exception>
793 public virtual async Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null)
794 {
795 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
796
797 using FileStream imageStream = File.OpenRead(imageFilePath);
798 return await GenerateImageVariationsAsync(imageStream, imageFilePath, imageCount, options).ConfigureAwait(false);
799 }
800
801 /// <summary> Generates variations of a given image. </summary>
802 /// <param name="imageFilePath">
803 /// The path of the image file to use as the basis for the variation. Must be a valid PNG file, less than 4MB,
804 /// and square. The provided file path's extension (for example: .png) will be used to validate the format of
805 /// the input image. The request may fail if the file path's extension and the actual format of the input image
806 /// do not match.
807 /// </param>
808 /// <param name="imageCount"> The number of image variations to generate. </param>
809 /// <param name="options"> The options to configure the image variation. </param>
810 /// <exception cref="ArgumentNullException"> <paramref name="imageFilePath"/> was null. </exception>
811 /// <exception cref="ArgumentException"> <paramref name="imageFilePath"/> is an empty string, and was expected to be non-empty. </exception>
812 public virtual ClientResult<GeneratedImageCollection> GenerateImageVariations(string imageFilePath, int imageCount, ImageVariationOptions options = null)
813 {
814 Argument.AssertNotNullOrEmpty(imageFilePath, nameof(imageFilePath));
815
816 using FileStream imageStream = File.OpenRead(imageFilePath);
817 return GenerateImageVariations(imageStream, imageFilePath, imageCount, options);
818 }
819
820 #endregion
821
822 private void CreateImageGenerationOptions(string prompt, int? imageCount, ref ImageGenerationOptions options)
823 {
824 options.Prompt = prompt;
825 options.N = imageCount;
826 options.Model = _model;
827 }
828
829 private void CreateImageEditOptions(Stream image, string imageFilename, string prompt, Stream mask, string maskFilename, int? imageCount, ref ImageEditOptions options)
830 {
831 options.Prompt = prompt;
832 options.N = imageCount;
833 options.Model = _model;
834 }
835
836 private void CreateImageVariationOptions(Stream image, string imageFilename, int? imageCount, ref ImageVariationOptions options)
837 {
838 options.N = imageCount;
839 options.Model = _model;
840 }
841}