openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
achandmsft-patch-1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/Custom/Images/ImageClient.cs

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