X

MAI-Image-2.5 Pro for .NET Developers — Microsoft’s Own Image Model Lands in Foundry

MAI-Image-2.5 Pro for .NET Developers

Every time a new image model ships, my first question isn’t “how pretty are the demo images.” It’s “can I actually put this in a pipeline and get consistent, controllable output.” Most image models are great at one beautiful hero shot and terrible at the boring part — generating twelve consistent product variants, or fixing one object in an image without regenerating the whole thing.

Microsoft AI just shipped MAI-Image-2.5 Pro, now available in public preview in Microsoft Foundry as an Azure Direct Model. It’s Microsoft’s own image generation and image-editing model — not a third-party model hosted in the catalog, but one built in-house by Microsoft AI.

That is worth pausing on. Alongside it, MAI-Voice-2 Flash also shipped for real-time voice through Azure Speech. This post is about the image model (I will cover MAI-Voice-2 Flash in another post), because that is the one .NET developers building content pipelines, e-commerce catalogs, or design tools will actually reach for first.


What MAI-Image-2.5 Pro Actually Does

It’s a diffusion-based text-to-image and image-to-image model. Two capabilities matter more than the others:

  • Generation — natural language prompt in, high-fidelity image out
  • Precise editing — targeted object edits, layout changes, text updates, and cleanup of artifacts like motion blur, all while preserving visual consistency across iterations

That second bullet is the interesting one. “Precise, surgical edits with consistency” is the phrase Microsoft uses, and it’s the right framing. A lot of image models will happily regenerate an entire scene when you ask for one small change — swap the color of a shirt and the model quietly redraws the face too. MAI-Image-2.5 Pro is positioned specifically to avoid that.

Why It Matters

  • Professional creative quality — stronger object consistency, more accurate text rendering (a famously hard problem for diffusion models), closer alignment to what you actually asked for, and better visual/world reasoning
  • More model choice in Foundry — you can now pick a purpose-built Microsoft model for creative workflows alongside the rest of the Foundry catalog, the same way you’d pick Kimi K2.7 Code for coding tasks or Cohere Command A+ for enterprise agents
  • Enterprise-ready foundations — backed by Microsoft’s safety and Responsible AI practices, running on Azure infrastructure for reliability, scale, and governance

Honestly, that last point is the one enterprises actually care about. A lot of image models are impressive right up until legal asks about content provenance and data handling.


Where This Fits — Real Use Cases

Microsoft calls out two buckets, and both map to real backlog items I’ve seen teams carry for months:

Campaigns and product content. Consistent hero assets, social media variants, retail signage, digital ads, product photography, e-commerce catalogs. The “consistency across iterations” capability is exactly what you need when you’re generating fifteen size/color variants of the same product shot and they all need to look like the same product line.

Storyboarding and regulated-industry visuals. Consistent scenes, characters, and concepts with stronger real-world accuracy — relevant for creative production, but also healthcare, financial services, and manufacturing, where “close enough” visual accuracy isn’t good enough.

If your team maintains a product catalog, a marketing asset pipeline, or anything that currently involves a human manually generating fifty variants of one image in Photoshop — this is worth a pilot.


Let’s Actually Call It from C#

Source code can be found at https://github.com/taswar/MAI-Image-2.5-Pro-Sample

Prerequisites

dotnet new console -n Mai-Image-2.5Pro-Demo
cd Mai-Image-2.5Pro-Demo
dotnet add package Azure.Core
dotnet add package Azure.Identity

Set your environment variables:

# On Windows (PowerShell)
$env:AZURE_AI_FOUNDRY_ENDPOINT = "https://YOUR-RESOURCE.services.ai.azure.com"
$env:AZURE_AI_IMAGE_MODEL = "MAI-Image-2.5-Pro"

Program.cs — Generate a Product Image

using Azure.Core;
using Azure.Identity;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var endpoint = Environment.GetEnvironmentVariable("AZURE_AI_FOUNDRY_ENDPOINT")
    ?? throw new InvalidOperationException("Set AZURE_AI_FOUNDRY_ENDPOINT.");

var model = Environment.GetEnvironmentVariable("AZURE_AI_IMAGE_MODEL") ?? "MAI-Image-2.5-Pro";

var prompt = """
    A minimalist product photo of a stainless steel water bottle on a plain
    white background, studio lighting, soft shadow beneath the bottle,
    e-commerce catalog style, no text on the label.
    """;

string url = $"{endpoint.TrimEnd('/')}/mai/v1/images/generations?api-version=preview";

var credential = new DefaultAzureCredential();
AccessToken token = await credential.GetTokenAsync(
    new TokenRequestContext(new[] { "https://cognitiveservices.azure.com/.default" }));

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);

var mai_payload = new
{
    prompt = prompt,
    model = model,
    width = 1024,
    height = 1024,
    output_compression = 100,
    output_format = "png",
    n = 1
};

using var content = new StringContent(
    JsonSerializer.Serialize(mai_payload),
    Encoding.UTF8,
    "application/json");

using HttpResponseMessage response = await http.PostAsync(url, content);
string responseBody = await response.Content.ReadAsStringAsync();

if (!response.IsSuccessStatusCode)
{
    Console.WriteLine($"Image generation failed: {(int)response.StatusCode} {response.ReasonPhrase}");
    Console.WriteLine(responseBody);
    throw new InvalidOperationException($"{model} image generation request failed.");
}

using JsonDocument json = JsonDocument.Parse(responseBody);
string? b64 = json.RootElement
    .GetProperty("data")[0]
    .GetProperty("b64_json")
    .GetString();

if (string.IsNullOrWhiteSpace(b64))
{
    throw new InvalidOperationException("Response did not contain data[0].b64_json.");
}

byte[] imageBytes = Convert.FromBase64String(b64);
string outputPath = Path.Combine(Environment.CurrentDirectory, "product-bottle.png");
await File.WriteAllBytesAsync(outputPath, imageBytes);
Console.WriteLine($"Image saved to: {outputPath}");

Editing an Existing Image — Targeted, Not a Full Regeneration

This is the part that matters more than pure generation. Here’s how you make one precise change to an existing product shot — swap the bottle color without touching the background, lighting, or shadow:

var editPrompt = """
    Change the bottle color from stainless steel to matte black.
    Keep the background, lighting, shadow, and camera angle exactly the same.
    """;

string editUrl = $"{endpoint.TrimEnd('/')}/mai/v1/images/edits?api-version=preview";

using var editContent = new MultipartFormDataContent
{
    { new StringContent(editPrompt), "prompt" },
    { new StringContent(model), "model" }
};

byte[] sourceImageBytes = await File.ReadAllBytesAsync(outputPath);
var imagePart = new ByteArrayContent(sourceImageBytes);
imagePart.Headers.ContentType = new MediaTypeHeaderValue("image/png");
editContent.Add(imagePart, "image", "product-bottle.png");

Console.WriteLine("Editing image...");

using HttpResponseMessage editResponse = await http.PostAsync(editUrl, editContent);
string editResponseBody = await editResponse.Content.ReadAsStringAsync();

if (!editResponse.IsSuccessStatusCode)
{
    Console.WriteLine($"Image edit failed: {(int)editResponse.StatusCode} {editResponse.ReasonPhrase}");
    Console.WriteLine(editResponseBody);
    throw new InvalidOperationException($"{model} image edit request failed.");
}

using JsonDocument editJson = JsonDocument.Parse(editResponseBody);
string? editB64 = editJson.RootElement
    .GetProperty("data")[0]
    .GetProperty("b64_json")
    .GetString();

if (string.IsNullOrWhiteSpace(editB64))
{
    throw new InvalidOperationException("Edit response did not contain data[0].b64_json.");
}

byte[] editedImageBytes = Convert.FromBase64String(editB64);
string editedOutputPath = Path.Combine(Environment.CurrentDirectory, "product-bottle-black.png");
await File.WriteAllBytesAsync(editedOutputPath, editedImageBytes);
Console.WriteLine($"Image saved to: {editedOutputPath}");

Expected Output

Generating image with MAI-Image-2.5-Pro...
Saved: product-bottle.png
Editing image...
Saved: product-bottle-black.png

Two files. Same lighting, same shadow, same camera angle. One bottle color changed. That is the workflow you’d wire into a service that generates every SKU variant overnight instead of a designer doing it by hand.

📝 Note: The exact SDK surface for Foundry image models is still settling as this model is in public preview — check the Foundry Model Catalog page for the current API reference before you wire this into production. The calling pattern above follows the standard Http Client image generation shape; MAI-Image models aren’t compatible with the Azure.AI.OpenAI SDK’s ImageClient — they require the raw REST call. Do confirmed against the latest docs, since things change very fast.


Why Run It Through Microsoft Foundry

Same reasoning as every other model I’ve covered in this series — Kimi K2.7 Code, Cohere Command A+ — but with one extra point specific to this model:

  • It’s a first-party Microsoft model. Support, roadmap, and Responsible AI documentation come from the same team building the platform you’re deploying on.
  • Entra ID auth — no separate API key management for yet another vendor.
  • Governance and safety tooling built into the platform, which matters more for image generation than most other model types — content policy and provenance questions come up fast in creative workflows.
  • Side-by-side evaluation against other Foundry models if you’re also experimenting with other image generation options.

Final Thoughts

MAI-Image-2.5 Pro is Microsoft betting on its own first-party model for a category — image generation — that has mostly been third-party territory in Foundry until now. The pitch isn’t “prettiest demo image.” It’s “precise edits with consistency,” which is the actual bottleneck for anyone trying to move image generation from a design toy into a production content pipeline.

If your team maintains product catalogs, marketing assets, or storyboards and you’re currently paying a human to manually generate every size and color variant — this is worth a pilot. Start with the generate-then-edit pattern above, point it at a real product shot, and see how many variants you can produce in a loop before lunch.


Resources

Categories: .NET Foundry
Taswar Bhatti:
Related Post