Table of Contents

Image Providers

Image providers answer one question: where does the source image come from? Every incoming request is offered to the registered providers in order, and the first provider whose Match function returns true owns the request.

That means provider order matters. If two providers can both match the same path, put the more specific one first or narrow its Match predicate so the wrong provider does not claim the request.

Default Physical Filesystem Provider

PhysicalFileSystemProvider is the default source provider registered by AddImageSharp().

using SixLabors.ImageSharp.Web;
using SixLabors.ImageSharp.Web.Providers;

builder.Services.AddImageSharp()
    .Configure<PhysicalFileSystemProviderOptions>(options =>
    {
        options.ProviderRootPath = "assets";
        options.ProcessingBehavior = ProcessingBehavior.CommandOnly;
    });

If you want a provider fixed to IWebHostEnvironment.WebRootFileProvider with no extra options, WebRootImageProvider is also available.

If you want truly command-only processing for local files, changing ProcessingBehavior is no longer sufficient on its own. You must also replace or suppress the default OnParseCommandsAsync behavior that inserts autoorient=true.

Provider Matching and Ordering

ImageSharp.Web stops at the first provider whose Match function returns true. It does not continue searching if that provider later decides the request is invalid, so keep these rules in mind:

  • Register more specific providers before more general ones.
  • Keep Match predicates mutually exclusive whenever possible.
  • Use InsertProvider(...) when provider precedence matters more than registration order.

Cloud providers in particular usually want a path prefix such as a container or bucket name so they can distinguish their requests cheaply.

Azure Blob Storage

Install the Azure provider package:

dotnet add package SixLabors.ImageSharp.Web.Providers.Azure

Then configure one or more containers:

using SixLabors.ImageSharp.Web;
using SixLabors.ImageSharp.Web.Azure.Providers;

builder.Services.AddImageSharp()
    .ClearProviders()
    .Configure<AzureBlobStorageImageProviderOptions>(options =>
    {
        options.BlobContainers.Add(new AzureBlobContainerClientOptions
        {
            ConnectionString = builder.Configuration["Azure:ConnectionString"]!,
            ContainerName = "public-images"
        });
    })
    .AddProvider<AzureBlobStorageImageProvider>();

Requests are matched by container name at the start of the path:

/public-images/avatars/jane.png?width=200

AzureBlobStorageImageProvider uses ProcessingBehavior.All, so it can serve both processed and commandless requests.

AWS S3

Install the AWS provider package:

dotnet add package SixLabors.ImageSharp.Web.Providers.AWS

Then configure one or more buckets:

using SixLabors.ImageSharp.Web;
using SixLabors.ImageSharp.Web.AWS.Providers;

builder.Services.AddImageSharp()
    .ClearProviders()
    .Configure<AWSS3StorageImageProviderOptions>(options =>
    {
        options.S3Buckets.Add(new AWSS3BucketClientOptions
        {
            BucketName = "public-images",
            Region = "us-east-1",
            AccessKey = builder.Configuration["AWS:AccessKey"],
            AccessSecret = builder.Configuration["AWS:SecretKey"]
        });
    })
    .AddProvider<AWSS3StorageImageProvider>();

Requests are matched by bucket name at the start of the path:

/public-images/avatars/jane.png?width=200

If your public URL shape does not naturally include the bucket name, use URL rewriting before ImageSharp.Web or implement a custom provider.

Implementing Your Own Provider

Implement IImageProvider when you need a new source backend. Your provider is responsible for three things:

  • deciding whether it owns the request via Match;
  • deciding whether the request is valid via IsValidRequest(...);
  • returning an IImageResolver that can open the source stream and report source metadata.

If your source already fits an IFileProvider-style model, FileProviderImageProvider is the easiest base class to start from.

Practical Guidance

  • Put providers in the order you want requests to be matched.
  • Keep original source storage separate from processed cache storage.
  • Return accurate source metadata so stale cache detection works.
  • Implement a custom provider only when existing filesystem, Azure, or S3 providers do not match the source model.