Generating Images from Text with C# and Open AI DALL-E
Ricardo
Posted on April 16, 2023
With the use of .NET C#, we can develop a POC (Proof of Concept) that uses the Open AI DALL-E model to generate images from text input.
In this blog post, we will explore the steps to develop a C# Console Application
using Open AI's DALL-E model to generate images from text.
Also, check out my blog with other articles --> https://rmauro.dev
๐ฌ What is DALL-E from Open AI
DALL-E can generate images of almost anything, from a yellow submarine to a pig with wings. It has been trained on a massive dataset of images and textual descriptions, allowing it to learn how to generate images from natural language input. In this article, we will explore how to integrate C# with DALL-E to generate images using code.
DALL-E Generated
๐งต Development with C
In this project we're going to use Visual Studio and C# with .NET 6 to create a Console Application.
๐ก You may need to do some tweaks if you intend to use another.NET version.
Step 1: Console Application and dependencies
Let's create our Console Application with C# and .NET 6 let's install the dependencies.
Project Name : ConsoleAppOpenAI.DALL_E
dotnet add Microsoft.Extensions.Http
๐ these are for loading configuration from JSON files
dotnet add Microsoft.Extensions.Configuration
dotnet add Microsoft.Extensions.Configuration.Json
๐ this is optional
dotnet add Microsoft.Extensions.Configuration.UserSecrets
Commands to install the dependencies
Installed Dependencies
Step 2: IOpenAIProxy Interface
Within this interface, we'll expose only the methods to Generate and Download the images from Open AI.
namespace ConsoleAppOpenAI.DALL_E.HttpServices;
public interface IOpenAIProxy
{
//๐ Send the Prompt Text with and return a list of image URLs
Task<GenerateImageResponse> GenerateImages(
GenerateImageRequest prompt,
CancellationToken cancellation = default);
//๐ Download the Image as byte array
Task<byte[]> DownloadImage(string url);
}
IOpenAIProxy.cs File
Step 3: Generate Image Models
Let's define our models using records. Records simplify the reading since they are only POCO classes.
namespace ConsoleAppOpenAI.DALL_E.HttpServices
{
public record class GenerateImageRequest(
string Prompt,
int N,
string Size);
public record class GenerateImageResponse(
long Created,
GeneratedImageData[] Data);
public record class GeneratedImageData(string Url);
}
Generate Image Models DTO
Step 4: Create an Open AI Account
To use the OpenAI API, we need to create an account on the OpenAI platform. The registration process is straightforward and can be completed in a few minutes.
- We just need to visit the OpenAI website at https://platform.openai.com/overview.
- Then click on the "Sign Up" button in the top right corner.
- Click on the button to start the registration process.
Step 5: Set up the Configuration File / appsettings.json
To access the DALL-E model, we'll need to set up the Subscription Id and API key for our application.
Collect them from these menus:
Update the appsettings.json
or secrets.json
file with the values.
{
"OpenAi": {
"OrganizationId": "{Subscription Id goes here}",
"ApiKey": "{API Key goes here}",
"Url": "https://api.openai.com",
"DALL-E": {
"Size": "1024x1024",
"N": 1
}
}
}
appsettings.json file
๐ก Don't forget to set Copy to Output Directory as Copy if newer for appsettings.json.
Step 6: Open AI HTTP Service Implementation
Create a class named OpenAIHttpService
with a single constructor receiving IConfiguration
and read the configuration we just set in place.
using ConsoleAppOpenAI.DALL_E.HttpServices;
using Microsoft.Extensions.Configuration;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
namespace ConsoleAppOpenAI.DALL_E.Services;
public class OpenAIHttpService : IOpenAIProxy
{
readonly HttpClient _httpClient;
readonly string _subscriptionId;
readonly string _apiKey;
public OpenAIHttpService(IConfiguration configuration)
{
//๐ reading settings from the configuration file
var openApiUrl = configuration["OpenAi:Url"] ?? throw new ArgumentException(nameof(configuration));
_httpClient = new HttpClient { BaseAddress = new Uri(openApiUrl) };
_subscriptionId = configuration["OpenAi:SubscriptionId"];
_apiKey = configuration["OpenAi:ApiKey"];
}
public async Task<GenerateImageResponse> GenerateImages(GenerateImageRequest prompt, CancellationToken cancellation = default)
{
throw new NotImplementedException();
}
public async Task<byte[]> DownloadImage(string url)
{
throw new NotImplementedException();
}
}
Next should be the implementation of the GenerateImages()
method:
public async Task<GenerateImageResponse> GenerateImages(GenerateImageRequest prompt, CancellationToken cancellation = default)
{
using var rq = new HttpRequestMessage(HttpMethod.Post, "/v1/images/generations");
var jsonRequest = JsonSerializer.Serialize(prompt, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
//serialize the content to JSON and set the correct content type
rq.Content = new StringContent(jsonRequest);
rq.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//๐ Including the Authorization Header with API Key
var apiKey = _apiKey;
rq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
//๐ Including the Subscription Id Header
var subscriptionId = _subscriptionId;
rq.Headers.TryAddWithoutValidation("OpenAI-Organization", subscriptionId);
var response = await _httpClient.SendAsync(rq, HttpCompletionOption.ResponseHeadersRead, cancellation);
response.EnsureSuccessStatusCode();
var content = response.Content;
var jsonResponse = await content.ReadFromJsonAsync<GenerateImageResponse>(cancellationToken: cancellation);
return jsonResponse;
}
Last the DownloadImage()
method implementation:
public async Task<byte[]> DownloadImage(string url)
{
var buffer = await _httpClient.GetByteArrayAsync(url);
return buffer;
}
Step 7: Consuming the APIs
Back to Program.cs
file let's wire everything together and start calling the APIs to generate images.
using ConsoleAppOpenAI.DALL_E.HttpServices;
using ConsoleAppOpenAI.DALL_E.Services;
using Microsoft.Extensions.Configuration;
using System.Reflection;
Console.WriteLine("Starting commandline for DALL-E [Open AI]");
var config = BuildConfig();
IOpenAIProxy aiClient = new OpenAIHttpService(config);
Console.WriteLine("Type your first Prompt");
var msg = Console.ReadLine();
var nImages = int.Parse(config["OpenAi:DALL-E:N"]);
var imageSize = config["OpenAi:DALL-E:Size"];
var prompt = new GenerateImageRequest(msg, nImages, imageSize);
var result = await aiClient.GenerateImages(prompt);
foreach (var item in result.Data)
{
Console.WriteLine(item.Url);
var fullPath = Path.Combine(Directory.GetCurrentDirectory(), $"{Guid.NewGuid()}.png");
var img = await aiClient.DownloadImage(item.Url);
await File.WriteAllBytesAsync(fullPath, img);
Console.WriteLine("New image saved at {0}", fullPath);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
static IConfiguration BuildConfig()
{
var dir = Directory.GetCurrentDirectory();
var configBuilder = new ConfigurationBuilder()
.AddJsonFile(Path.Combine(dir, "appsettings.json"), optional: false)
.AddUserSecrets(Assembly.GetExecutingAssembly());
return configBuilder.Build();
}
With all of this, we should have a running POC integrating with DALL-E model.
Generate our very first Image
Here is the output of my first try.
Prompt: Wide and green garden with a lot of flowers, with sunflowers, and a small dog running around
Take a look at this beautiful image generated by our application and DALL-E.
Conclusion
Integrating C# with DALL-E is a straightforward process that allows us to generate images programmatically.
By using Open AI's API, we can easily send textual descriptions and receive high-quality images in response.
This integration opens up many possibilities, such as generating images for data visualization, creating custom artwork, or automating image creation tasks. As DALL-E continues to improve, we can expect even more exciting applications in the future.
Source code at: https://github.com/ricardodemauro/OpenAILabs.Console
Posted at: https://rmauro.dev/generating-images-from-text-with-csharp-and-open-ai-dall-e/
Posted on April 16, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.