Github repo for this demo
Dall-e-3 image generator with semantic kernelThe demo contains two steps, first building the semantic kernel itself and then the image generation. First off, the .csproj file has package references to the latest as of March 2025 nuget package of Microsoft Semantic Kernel.
DalleImageGeneratorWithSemanticKernel.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CS8618,IDE0009,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0020,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0101,SKEXP0110</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" Version="1.44.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
</ItemGroup>
</Project>
Note that multiple warnings are marked as no warning as semantic kernel is open for change in the future and thus flags multiple different warnings.
The image generation demo is set up like this in the class ImageGeneration.
Note how the Kernel object is built up here. It got a builder that offers many methods to add AI services. In this case we add an ITextToImageService.
The modelName used here is "dall-e-3".
ImageGeneration.cs
using DalleImageGeneratorWithSemanticKernel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.TextToImage;
using OpenAI.Images;
using System;
using System.Diagnostics;
namespace UseSemanticKernelFromNET;
public class ImageGeneration
{
public async Task GenerateBasicImage(string modelName)
{
Kernel kernel = Kernel
.CreateBuilder()
.AddOpenAITextToImage(modelId:modelName, apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")!).Build();
ITextToImageService imageService = kernel.GetRequiredService<ITextToImageService>();
Console.WriteLine("##### SEMANTIC KERNEL - IMAGE GENERATOR DALL-E-3 CONSOLE APP #####\n\n");
string prompt =
"""
In the humorous image, Vice President JD Vance and his wife are seen stepping out of their plane onto the icy runway of
Thule Air Base. Just as they set foot on the frozen ground, a bunch of playful polar bears greet them enthusiastically, much like
overzealous fans welcoming celebrities. The surprised expressions on their faces are priceless as the couple finds
themselves being "chased" by these bundles of fur and excitement. JD Vance, with a mix of amusement and alarm, has one
shoe comically left behind in the snow, while his wife, holding onto her hat against the chilly wind, can't suppress a laugh.
The scene is completed with members of the Air Base
staff in the background, chuckling and capturing the moment on their phones, adding to the light-heartedness of the unexpected encounter.
The plane should carry the AirForce One Colors and read "United States of America".
""";
Console.WriteLine($"\n ### STORY FOR THE IMAGE TO GENERATE WITH DALL-E-3 ### \n{prompt}\n\n");
Console.WriteLine("\n\nStarting generation of dall-e-3 image...");
var cts = new CancellationTokenSource();
var cancellationToken = cts.Token;
var rotationTask = Task.Run(() => ConsoleUtil.RotateDash(cancellationToken), cts.Token);
var image = await imageService.GetOpenAIImageContentAsync(prompt,
kernel: kernel,
size: (1024, 1024), //for Dall-e-2 images, use: 256x256, 512x512, or 1024x1024. For dalle-3 images, use: 1024x1024, 1792x1024, 1024x1792.
style: "vivid",
quality: "hd", //high
responseFormat: "b64_json", // bytes
cancellationToken: cancellationToken);
cts.Cancel(); //cancel to stop animating the waiting indicator
var imageTmpFilePng = Path.ChangeExtension(Path.GetTempFileName(), "png");
image?.FirstOrDefault()?.WriteToFile(imageTmpFilePng);
Console.WriteLine($"Wrote image to location: {imageTmpFilePng}");
Process.Start(new ProcessStartInfo
{
FileName = "explorer.exe",
Arguments = imageTmpFilePng,
UseShellExecute = true
});
}
}
A helper extension method has been added for the Open AI Dall-e-3 image creation.
Please note that one should stick to not too many extension methods of semantic kernel itself as this defeats the purpose of a standardized way of using the semantic kernel.
But in this case, it is just a helper method to customize the generation of particularly dall-e-3 (and dall-e-2) images from Open AI using the Semantic kernel.
The code is shown below
TextToImageServiceExtensions.cs
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Services;
using Microsoft.SemanticKernel.TextToImage;
namespace UseSemanticKernelFromNET;
public static class TextToImageServiceExtensions
{
/// <summary>
/// Generates OpenAI image content asynchronously based on the provided text input and settings.
/// </summary>
/// <param name="imageService">The image service used to generate the image content.</param>
/// <param name="input">The text input used to generate the image.</param>
/// <param name="kernel">An optional kernel instance for additional processing.</param>
/// <param name="size">
/// The desired size of the generated image. For DALL-E 2 images, use: 256x256, 512x512, or 1024x1024.
/// For DALL-E 3 images, use: 1024x1024, 1792x1024, or 1024x1792.
/// </param>
/// <param name="style">The style of the image. Must be "vivid" or "natural".</param>
/// <param name="quality">The quality of the image. Must be "standard", "hd", or "high".</param>
/// <param name="responseFormat">
/// The format of the response. Must be one of the following: "url", "uri", "b64_json", or "bytes".
/// </param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>
/// A task that represents the asynchronous operation. The task result contains a read-only list of
/// <see cref="ImageContent"/> objects representing the generated images.
/// </returns>
public static Task<IReadOnlyList<ImageContent>> GetOpenAIImageContentAsync(this ITextToImageService imageService,
TextContent input,
Kernel? kernel = null,
(int width, int height) size = default((int, int)), // for Dall-e-2 images, use: 256x256, 512x512, or 1024x1024. For dalle-3 images, use: 1024x1024, 1792x1024, 1024x1792.
string style = "vivid",
string quality = "hd",
string responseFormat = "b64_json",
CancellationToken cancellationToken = default)
{
string? currentModelId = imageService.GetModelId();
if (currentModelId != "dall-e-3" && currentModelId != "dall-e-2")
{
throw new NotSupportedException("This method is only supported for the DALL-E 2 and DALL-E 3 models.");
}
if (size.width == 0 || size.height == 0)
{
size = (1024, 1024); //defaulting here to (1024, 1024).
}
if (currentModelId == "dall-e-2"){
var supportedSizes = new[]{
(256, 256),
(512, 512),
(1024, 1024)
};
if (!supportedSizes.Contains(size))
{
throw new ArgumentException("For DALL-E 2, the size must be one of: 256x256, 512x512, or 1024x1024.");
}
}
else if (currentModelId == "dall-e-3")
{
var supportedSizes = new[]{
(1024, 1024),
(1792, 1024),
(1024, 1792)
};
if (!supportedSizes.Contains(size))
{
throw new ArgumentException("For DALL-E 3, the size must be one of: 256x256, 512x512, or 1024x1024.");
}
}
return imageService.GetImageContentsAsync(
input,
new OpenAITextToImageExecutionSettings
{
Size = size,
Style = style, //must be "vivid" or "natural"
Quality = quality, //must be "standard" or "hd" or "high"
ResponseFormat = responseFormat // url or uri or b64_json or bytes
},
kernel,
cancellationToken);
}
}
Screenshot of this demo, console app running:
The console app will generate the dall-e-3 image using OpenAI service for this and save the image as a PNG image and save it into file saved into a temporary location and then open this image using Windows default image viewer application.
Example image generated :