---
title: "Resize an image in C#"
url: https://recursiveai.org/oneimage/articles/resize-image-csharp/
description: "Resize images in C# on any OS with pure .NET code: keep the aspect ratio, fit or crop to a box, make thumbnails, set JPEG quality and resize ASP.NET Core uploads."
date: 2026-10-23
author: OneImage team
---

# Resize an image in C#

Resize images in C# on any OS with pure .NET code: keep the aspect ratio, fit or crop to a box, make thumbnails, set JPEG quality and resize ASP.NET Core uploads.

October 23, 2026 · OneImage team

To resize an image in C#, load it, call `Resize` with the width you want and save it. With OneImage that’s one line, `Image.Load("photo.jpg").Resize(width: 800).Save("photo-800.jpg")`, and the height follows the aspect ratio. It is pure C#, so the same code runs on Windows, Linux, macOS and in containers, unlike System.Drawing, which is Windows-only on current .NET. Below: fitting and cropping to a box, thumbnails, not enlarging small images, quality settings, several sizes at once and ASP.NET Core uploads. Every sample was run against OneImage 1.6.0 on .NET 10.

*Terminal · NuGet*

```
dotnet add package RecursiveAI.OneImage
```

OneImage targets .NET 10. The examples use a 3000×3002 photograph (`photo.jpg`) and a phone-style photo stored as 1200×800 with an EXIF orientation of 6, meaning “rotate 90° to display”, and a GPS position (`portrait.jpg`).

## Resize to a width and keep the aspect ratio

*Program.cs · .NET 10*

```
using OneImage;
 
// 800 px wide; the height follows the aspect ratio.
Image.Load("photo.jpg").Resize(width: 800).Save("photo-800.jpg");
```

The 3000×3002 photo becomes 800×801. Give only `height:` to fix the height instead. The output format comes from the extension, so `.png`, `.webp`, `.gif`, `.tif`, `.bmp` or `.ico` work the same way. Nothing is decoded until `Save`, and for JPEG input the decoder reads the image at 1/2, 1/4 or 1/8 scale when that is enough for the target size, so a large photo isn’t held in memory at full resolution.

## Resize to a fixed size: fit, crop or pad

Give both a width and a height and choose how the image fills that box with `fit:`

*Program.cs · .NET 10*

```
using OneImage;
 
Image photo = Image.Load("photo.jpg");
 
// Fit inside 800x600 (Fit.Contain is the default): 600x600 for a square photo.
photo.Resize(width: 800, height: 600).Save("contain.jpg");
 
// Fill 800x600 exactly and crop what overflows, keeping the center.
photo.Resize(width: 800, height: 600, fit: Fit.Cover).Save("cover.jpg");
 
// Fit inside 800x600 and pad the rest with white.
photo.Resize(width: 800, height: 600, fit: Fit.Pad, background: new Rgba32(255, 255, 255, 255))
     .Save("pad.jpg");
```

These wrote 600×600, 800×600 and 800×600 files. `Image` is immutable, so one loaded photo can feed all three.

| `Fit` | Result |
|---|---|
| `Contain` (default) | Fits inside the box; aspect ratio kept; one side may be smaller. |
| `Cover` | Fills the box; aspect ratio kept; the overflow is cropped. Choose the kept part with `anchor:` (nine positions, or `Anchor.Smart`, which picks the busiest area). |
| `Pad` | Fits inside the box, then pads to the exact size with `background:`. |
| `BoxPad` | Like `Pad`, but never enlarges. |
| `Min` | Covers the box without cropping; never enlarges. |
| `Stretch` | Exactly the box; aspect ratio not kept. |

## Create a thumbnail in C#

For images that go on the web, use `Image.Thumbnail`. It is `Resize` with the defaults a published copy needs:

*Program.cs · .NET 10*

```
using OneImage;
 
// Upright, at most 400 px wide, never enlarged, sRGB, EXIF and GPS removed.
Image.Thumbnail("portrait.jpg", 400).Save("portrait-400.jpg");
 
// A 200x200 square that fills the box, for avatars and grids.
Image.Thumbnail("portrait.jpg", 200, 200, fit: Fit.Cover).Save("portrait-square.jpg");
```

In order, it applies the EXIF orientation, resizes (never larger than the original unless you pass `upscale: true`), converts to sRGB with a compact embedded profile and removes EXIF, XMP and IPTC. The portrait stored sideways at 1200×800 came out upright at 400×600, and the square at 200×200, both with no EXIF block, so no GPS position. Phone photos are the usual source of “my resized image is rotated”: the pixels are stored sideways and the orientation tag says how to show them (see [EXIF orientation in C#](https://recursiveai.org/oneimage/articles/exif-orientation-csharp/)). OneImage applies that tag when it loads, in `Load` as well as in `Thumbnail`.

## Don’t enlarge small images

`Resize` gives you the size you asked for, even if that means enlarging. Pass `upscale: false` when the target is a maximum:

*Program.cs · .NET 10*

```
using OneImage;
 
// Resize enlarges when asked to; upscale: false stops at the original size.
// portrait.jpg is 800x1200 once upright, so this writes 800x1200, not 2000x3000.
Image.Load("portrait.jpg").Resize(width: 2000, upscale: false).Save("not-enlarged.jpg");
```

A plain `Load` and `Save` keeps the metadata, so this file still carries the GPS block. That’s right for archiving. For anything public, use `Thumbnail` or call `StripMetadata()` before saving.

## Resize without losing quality

Two settings decide how a resized image looks: the resampling filter and the encoder quality.

*Program.cs · .NET 10*

```
using OneImage;
 
var jpeg = new SaveOptions { EncoderOptions = new JpegEncoderOptions { Quality = 85 } };
 
Image.Load("photo.jpg")
     .Resize(width: 1200, filter: ResamplingFilter.Lanczos3)
     .Save("photo-1200.jpg", jpeg);
```

- **Filter.** The default, `Auto`, already uses Lanczos3 when shrinking and Catmull-Rom when enlarging, so you rarely need to set one. `Mitchell` is softer, and `Nearest` keeps hard pixel edges for pixel art and icons.
- **Linear light.** Resampling runs in linear light on premultiplied alpha, so transparent edges don’t pick up color from fully transparent pixels. Pass `linear: false` to filter the stored values instead.
- **JPEG quality.** The default is 75 on the libjpeg scale. Here 85 gave a 1200×1201 file of 298 KB. For smaller files at the same look, write WebP instead; see our guide to [converting images to WebP in C#](https://recursiveai.org/oneimage/articles/convert-image-to-webp-csharp/).

## Make several sizes from one image

Responsive images need the same picture at several widths. Load once and derive each size:

*Program.cs · .NET 10*

```
using OneImage;
 
Image photo = Image.Load("photo.jpg");   // nothing is decoded yet
 
foreach (int width in new[] { 320, 640, 1280 })
{
    photo.Resize(width: width, upscale: false).Save($"photo-{width}.webp");
}
```

This wrote 320×320, 640×640 and 1280×1281 WebP files of 34, 72 and 166 KB, ready for a `srcset`.

## Resize uploaded images in ASP.NET Core

The same calls take a `Stream`. This minimal API endpoint stores every upload as an upright JPEG at most 1600 px wide, with private metadata removed:

*Program.cs · ASP.NET Core · .NET 10*

```
using OneImage;
 
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
 
string folder = Path.Combine(app.Environment.ContentRootPath, "uploads");
Directory.CreateDirectory(folder);
 
app.MapPost("/photos", async (IFormFile file) =>
{
    try
    {
        await using Stream upload = file.OpenReadStream();
        Image photo = Image.Thumbnail(upload, 1600);   // upright, at most 1600 px wide, no EXIF/GPS
 
        string name = $"{Guid.NewGuid():N}.jpg";
        await photo.SaveAsync(Path.Combine(folder, name));
        return Results.Ok(new { name, photo.Width, photo.Height });
    }
    catch (ImageException ex) // not an image, damaged, or over the size limits
    {
        return Results.BadRequest(ex.Message);
    }
}).DisableAntiforgery();
 
app.Run();
```

Posting the two test photos returned `{"width":1600,"height":1601}` and `{"width":800,"height":1200}`. The portrait was turned upright and not enlarged, and neither stored file had an EXIF block. A text file got a 400 with “The data is not in a recognized image format.” Uploads are untrusted, so OneImage’s size limits are on by default and are checked from the file headers before large buffers are allocated ([limits](https://recursiveai.org/oneimage/docs/guide/#limits)).

If you’d rather resize on request than on upload, with URLs like `/photos/a.jpg?width=400`, the [OneImage.Web](https://recursiveai.org/oneimage/docs/web/) middleware does that with a disk cache.

## What about System.Drawing, SkiaSharp and ImageSharp?

- **System.Drawing** (`Bitmap`, `Graphics.DrawImage`) is the answer in most older posts. Since .NET 6 it is supported only on Windows, and on Linux or macOS it throws “System.Drawing.Common is not supported on this platform” or a similar error. Our page on [fixing that error](https://recursiveai.org/oneimage/articles/system-drawing-common-not-supported/) explains why and maps the common calls.
- **SkiaSharp and ImageSharp** both resize well. SkiaSharp wraps native Skia binaries per platform (on Linux you add them yourself; see [SkiaSharp on Linux and Docker](https://recursiveai.org/oneimage/articles/skiasharp-linux-docker/)), and recent ImageSharp releases need a Six Labors license key to build. Our [ImageSharp alternatives](https://recursiveai.org/oneimage/articles/imagesharp-alternatives/) comparison covers both, with sources.

OneImage’s [published benchmarks](https://recursiveai.org/oneimage/docs/performance/) include JPEG and WebP thumbnail tasks against ImageSharp, SkiaSharp, NetVips and Magick.NET, with memory use, the losses and the method. For everything else it does, see the [overview](https://recursiveai.org/oneimage/).
