Skip to main content
  1. Posts/

DALL-E Art-Generator with C# .NET

·5 mins

We will explore how to use the DALL-E Image Generator in conjunction with C# .NET.

With just a few steps, we’ll develop a small POC (Proof of Concept) that uses the DALL-E model to generate images from text phrases using C#.

What is DALL-E Art-Generator #

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.

DALL·E 2 is an AI system that can create realistic images and art from a description in natural language.
https://openai.com/research/dall-e

Dog running on the garden - generated by DALL-E

DALL-E Generated

Getting Started with C# and DALL-E #

In this project, we will use Visual Studio and C# and .NET 6 to create the Console Application.

💡

You may also work with different framework versions.

Step 1: Create the Console Application and Install the Dependencies #

Let’s create our Console Application with C# and .NET 6 and install the required 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

Command to add dependencies

Visual Studio Nuget Package List

Installed Dependencies

Step 2: Create the 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);
}

The IOpenAIProxy Interface

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);
}

Record classes to Generate Image Models

Step 4: Create an Open AI Account #

We need to create an account on the Open AI platform to use the Open AI API.

The registration process is straightforward and can be completed in a few minutes.

  • We need to visit the Open AI website at https://platform.openai.com/overview.
  • Then click 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 #

To access the DALL-E model, we’ll need to set up our application’s Subscription Id and API key.
Collect them from these menus:

Settings Menu of Open AI website

Settings Menu of Open AI Website

Then update the appsettings.json 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

💡

Remember to set property Copy to Output Directory with Copy if newer for appsettings.json file.

Step 6: Open AI HTTP Service Implementation #

Create a class named OpenAIHttpService with a single constructor receiving the 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();
    }
}

Barebones of OpenAIHttpService Class

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;
}

Generate Images Implementation

Then the last step is the DownloadImage() method implementation:

public async Task<byte[]> DownloadImage(string url)
{
    var buffer = await _httpClient.GetByteArrayAsync(url);

    return buffer;
}

DownloadImage method Implementation

Step 7: Consuming the APIs #

Back to the file Program.cs, 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()}.webp");
	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 this, we have a complete Application with the DALL-E Art-Generator.

Generate our very first Image #

Run the Application and it try yourself.
Here is my first run:

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:

DALL-E Generated

Conclusion #

Integrating C# with DALL-E is a straightforward process allowing us to programmatically generate images.

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.

💡

Source Code available at:
https://github.com/ricardodemauro/OpenAILabs.Console