WebP cuts image file sizes by 25–35% versus JPEG at equivalent quality — critical for web performance. In .NET, ImageSharp is the most deployment-friendly option because it's 100% managed code. Magick.NET gives more fine-grained control over WebP encoding settings. The ChangeThisFile API is the right call for serverless functions or any environment where you want zero native deps.

Method 1: Magick.NET (libwebp, rich encoding options)

Magick.NET wraps ImageMagick's libwebp encoder. Full control over lossless vs lossy, quality, method (speed vs compression ratio).

dotnet add package Magick.NET-Q16-AnyCPU
using ImageMagick;

public static class JpgToWebp
{
    /// <summary>Converts a JPG file to WebP with configurable quality.</summary>
    public static void Convert(string inputPath, string outputPath, int quality = 80)
    {
        using var image = new MagickImage(inputPath);

        // Method 6 = best compression (slower). Range: 0-6.
        image.Settings.SetDefine(MagickFormat.WebP, "method", "6");
        image.Quality = (uint)quality;
        image.Format = MagickFormat.WebP;

        image.Write(outputPath);
    }

    /// <summary>Batch convert a directory of JPGs to WebP.</summary>
    public static void ConvertDirectory(string inputDir, string outputDir, int quality = 80)
    {
        Directory.CreateDirectory(outputDir);
        foreach (var file in Directory.EnumerateFiles(inputDir, "*.jpg",
            SearchOption.TopDirectoryOnly))
        {
            var outPath = Path.Combine(outputDir,
                Path.GetFileNameWithoutExtension(file) + ".webp");
            Convert(file, outPath, quality);
        }
    }
}

// Usage
JpgToWebp.Convert("photo.jpg", "photo.webp", quality: 80);

Quality 75–85 is the sweet spot for photographic content — visually lossless with 25–35% smaller files than JPEG. For icons and simple graphics, try lossless: image.Settings.SetDefine(MagickFormat.WebP, "lossless", "true").

Method 2: ImageSharp (pure .NET, no native deps)

ImageSharp is entirely managed .NET — no libwebp, no native binaries. Best choice for containers and cross-platform deploys that need a minimal footprint.

dotnet add package SixLabors.ImageSharp
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Webp;

public static class JpgToWebpSharp
{
    public static async Task ConvertAsync(
        string inputPath,
        string outputPath,
        int quality = 80,
        CancellationToken ct = default)
    {
        using var image = await Image.LoadAsync(inputPath, ct);

        var encoder = new WebpEncoder
        {
            Quality = quality,
            Method = WebpEncodingMethod.BestQuality, // 0-6, higher = slower + smaller
            FileFormat = WebpFileFormatType.Lossy
        };

        await using var outStream = File.Create(outputPath);
        await image.SaveAsync(outStream, encoder, ct);
    }

    public static async Task ConvertBatchAsync(
        IEnumerable<string> inputPaths,
        string outputDir,
        int quality = 80,
        CancellationToken ct = default)
    {
        Directory.CreateDirectory(outputDir);
        foreach (var path in inputPaths)
        {
            var outPath = Path.Combine(outputDir,
                Path.GetFileNameWithoutExtension(path) + ".webp");
            await ConvertAsync(path, outPath, quality, ct);
        }
    }
}

ImageSharp is MIT-licensed. The Six Labors Split License applies to businesses with >1M USD/year revenue — check the pricing page if your project is at that scale.

Method 3: ChangeThisFile API (HttpClient, no native deps)

POST the JPG, receive WebP. Source format is auto-detected. Free tier: 1,000 conversions/month.

# Verify with curl first
curl -X POST https://changethisfile.com/v1/convert \
  -H "Authorization: Bearer ctf_sk_your_key" \
  -F "file=@photo.jpg" \
  -F "target=webp" \
  --output photo.webp
using System.Net.Http;
using System.Net.Http.Headers;

public class ImageConvertService
{
    private readonly HttpClient _http;
    private const string ApiKey = "ctf_sk_your_key_here";

    public ImageConvertService(IHttpClientFactory factory)
        => _http = factory.CreateClient("ctf");

    public async Task<byte[]> JpgToWebpAsync(
        Stream jpgStream,
        string fileName,
        CancellationToken ct = default)
    {
        using var form = new MultipartFormDataContent();

        var fileContent = new StreamContent(jpgStream);
        fileContent.Headers.ContentType =
            new MediaTypeHeaderValue("image/jpeg");
        form.Add(fileContent, "file", fileName);
        form.Add(new StringContent("webp"), "target");

        using var request = new HttpRequestMessage(HttpMethod.Post, "/v1/convert")
        {
            Content = form,
            Headers = { Authorization =
                new AuthenticationHeaderValue("Bearer", ApiKey) }
        };

        using var response = await _http.SendAsync(request, ct);
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsByteArrayAsync(ct);
    }
}

When to use each

ApproachBest forTradeoff
Magick.NETFine-grained WebP encoding, lossless option, existing ImageMagick pipelineNative libwebp bundled; larger NuGet package
ImageSharpPure .NET, minimal container footprint, async-first APISix Labors license at high revenue; slightly slower than libwebp
ChangeThisFile APIServerless, no native deps at all, free tierNetwork call; 25MB file limit on free tier

Production tips

  • Quality 80 is the right default. WebP at 80 is visually lossless for most photographic content and 25–35% smaller than JPEG 90. Go to 60–70 for thumbnails where pixel-peeping won't happen.
  • Use async file I/O throughout. ImageSharp's async API pairs cleanly with async controller actions. Use Image.LoadAsync and SaveAsync to avoid blocking thread-pool threads on I/O.
  • Use IHttpClientFactory for the API. Register a named client in Program.cs and inject IHttpClientFactory — avoids socket exhaustion on high-volume image endpoints.
  • Parallelize batch conversions with SemaphoreSlim. For batch jobs, use Parallel.ForEachAsync (.NET 6+) or a SemaphoreSlim to cap concurrency and avoid memory pressure from too many images loaded simultaneously.
  • Resize before converting for web thumbnails. Both Magick.NET and ImageSharp support resize + convert in a single pass — process the image once, not twice.

ImageSharp is the cleanest drop-in for most .NET projects — no native deps, MIT license, and fully async. Magick.NET is the better choice when you need lossless WebP or already have an ImageMagick pipeline. The ChangeThisFile API eliminates both for low-to-medium volume workloads. Free tier: 1,000 conversions/month.