> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/ai-in-umbraco/19.latest/using-the-api/image-generation/editing-images.md).

# Editing Images

Edit existing images with a prompt (maskless), and reach the provider-native client for masked outpainting.

{% hint style="warning" %}
Image Generation is experimental and disabled by default. See [Enabling image generation](/ai-in-umbraco/19.latest/using-the-api/image-generation.md#enabling-image-generation).
{% endhint %}

## Maskless edit (Tier 2)

Supply one or more original images alongside the prompt. The model transforms the supplied image(s) rather than generating from scratch. Use the `GenerateImagesAsync` overload that takes `originalImages`:

{% code title="EditImage.cs" %}

```csharp
#pragma warning disable UMBRACOAI_IMAGEGEN

using Microsoft.Extensions.AI;
using Umbraco.AI.Core.ImageGeneration;

public async Task<IList<AIContent>> AddSnow(byte[] originalPng)
{
    var original = new DataContent(originalPng, "image/png");

    var response = await _imageGenerationService.GenerateImagesAsync(
        img => img.WithAlias("seasonal-edit").WithProfile("marketing-images"),
        "Add a light dusting of snow to the scene",
        new AIContent[] { original });

    return response.Contents;
}
```

{% endcode %}

{% hint style="info" %}
Not every model supports editing. Check the `image.supportsEdit` constraint from [`GetSupportedModelsAsync`](/ai-in-umbraco/19.latest/using-the-api/image-generation/generating-images.md#validating-models-and-sizes-up-front) before offering an edit workflow.
{% endhint %}

## Masked outpainting (Tier 3)

Masked editing (supplying a mask to control which region changes) is not expressible through the Microsoft.Extensions.AI abstraction. For it, reach the provider-native client through the scoped generator's `GetService`.

`CreateImageGeneratorAsync` returns an `IImageGenerator` that forwards `GetService` through the full pipeline. For OpenAI, resolve the un-bound `OpenAIClient` and pick your model and size at call time:

{% code title="MaskedEdit.cs" %}

```csharp
#pragma warning disable UMBRACOAI_IMAGEGEN

using OpenAI;

var generator = await _imageGenerationService.CreateImageGeneratorAsync(
    img => img.WithAlias("masked-outpaint").WithProfile("marketing-images"));

var openAiClient = (OpenAIClient?)generator.GetService(typeof(OpenAIClient));
var imageClient = openAiClient!.GetImageClient("gpt-image-1");

// Use imageClient's native mask/edit APIs here.
```

{% endcode %}

{% hint style="warning" %}
Resolving `OpenAIClient` through `GetService` is OpenAI specific — other providers will not return one. Raw calls made this way **bypass the usage and audit middleware**. To keep them visible in analytics and audit, wrap them in `InvokeWithTrackingAsync` (below).
{% endhint %}

## Keeping raw calls tracked

`InvokeWithTrackingAsync` opens a scope, builds the scoped generator, runs your operation, and records usage + audit around it. Return an `AITrackedImageResult<TResult>` reporting what the raw call produced:

{% code title="TrackedRawCall.cs" %}

```csharp
#pragma warning disable UMBRACOAI_IMAGEGEN

using Microsoft.Extensions.AI;
using OpenAI;
using Umbraco.AI.Core.ImageGeneration;

var tracked = await _imageGenerationService.InvokeWithTrackingAsync(
    img => img.WithAlias("masked-outpaint").WithProfile("marketing-images"),
    async (generator, ct) =>
    {
        var client = (OpenAIClient)generator.GetService(typeof(OpenAIClient))!;
        var imageClient = client.GetImageClient("gpt-image-1");

        // ... perform the provider-native masked edit, obtain bytes ...
        byte[] resultBytes = await DoMaskedEditAsync(imageClient, ct);

        return new AITrackedImageResult<byte[]>
        {
            Result = resultBytes,
            ImageCount = 1,
        };
    });

byte[] edited = tracked.Result;
```

{% endcode %}

## Related

* [Generating Images](/ai-in-umbraco/19.latest/using-the-api/image-generation/generating-images.md) - Text-to-image and model validation
* [Image Generation overview](/ai-in-umbraco/19.latest/using-the-api/image-generation.md) - Enablement and service surface
* [OpenAI Provider](/ai-in-umbraco/19.latest/providers/openai.md) - The provider that supports the escape hatch


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umbraco.com/ai-in-umbraco/19.latest/using-the-api/image-generation/editing-images.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
