← All articles

Resizing an image without distorting it

A thumbnail should fit its box without stretching the image. Compute one scale factor and apply it to both dimensions.

t.Turgay
Resizing an image without distorting it

Fitting an image inside a 200×200 box is different from turning it into a 200×200 square. The first preserves its aspect ratio; the second requires a cropping or stretching decision. That distinction is the starting point for explaining Bitmap-based thumbnail code from my archive.

Scale by the tighter constraint

For a 1200×800 photograph inside a 200×200 limit, the width ratio is 200/1200 and the height ratio is 200/800. Selecting the smaller ratio produces approximately 200×133. Scaling each dimension independently to 200 would distort the image. The additional minimum with one prevents upscaling an already small source.

using System.Drawing;
using System.Drawing.Drawing2D;
static void Thumbnail(string source, string destination, int maxWidth, int maxHeight)
{
    if(maxWidth <= 0 || maxHeight <= 0) throw new ArgumentOutOfRangeException();
    using var input = Image.FromFile(source);
    var ratio = Math.Min(1d, Math.Min((double)maxWidth/input.Width, (double)maxHeight/input.Height));
    var width = Math.Max(1, (int)Math.Round(input.Width*ratio));
    var height = Math.Max(1, (int)Math.Round(input.Height*ratio));
    using var output = new Bitmap(width,height);
    using var graphics = Graphics.FromImage(output);
    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphics.DrawImage(input,0,0,width,height);
    output.Save(destination, System.Drawing.Imaging.ImageFormat.Png);
}

Both maximum dimensions must be positive. Rounding is clamped to at least one pixel. The method draws into a new Bitmap and writes PNG bytes, so the destination name and served MIME type must match that format. A .jpg suffix does not turn this encoder's output into JPEG.

Keep the platform requirement explicit

System.Drawing.Common should be treated as a Windows-specific dependency in modern .NET. A Windows archive example is not automatically portable to a Linux Docker image. A server that needs Linux image processing requires a supported library with its own version and licensing review. This code explains an existing Bitmap technique; it is not a ready-made image service for the portfolio's Linux host.

Interpolation depends on the visual material

HighQualityBicubic can be a reasonable choice for photographic downscaling. It can also blur the deliberately sharp blocks of pixel art by introducing intermediate colors. Preserving pixel boundaries may instead call for nearest-neighbor interpolation and suitable integer scaling ratios. A setting named “high quality” does not define one correct visual result for every kind of image.

EXIF orientation can matter before the dimensions are calculated. A phone photograph may depend on orientation metadata; using raw pixel dimensions without applying that orientation can produce a correctly scaled but sideways preview. Transparency, color profiles and encoding settings also deserve inspection against representative inputs.

Disposal is part of correctness

Image, Bitmap and Graphics can own unmanaged resources. Their using scopes establish when those resources are released. Image.FromFile also creates a lifetime relationship with the source file, so writing over that same path can fail; a separate target or a validated temporary replacement is clearer. Repeated processing is a better resource test than a single successful console run.

A small compressed input can still declare a huge image. Set bounds on uploaded bytes, dimensions and total pixel count. Decode failures should become a useful user-facing failure without exposing private server paths or logging the complete file.

Cache the transformation, not merely the source ID

If one image has several previews, its identity alone is not a sufficient cache key. Source version, target bounds, crop policy and output format can all affect the result. Updating the source while continuing to show an old thumbnail is a separate consistency issue even when the resize operation itself is correct.

Test landscape and portrait inputs, a small image and an unusually narrow one. The output must stay within the box, preserve the ratio and avoid unwanted upscaling. Then inspect an oriented photograph, a transparent PNG and pixel art. Passing the numeric size checks alone does not prove the preview looks right.

System.Drawing platform support; InterpolationMode options.

✳ You have reached the end of this orbit.
Explore more articles →
turgay.A little code, a few pixels, a lot of curiosity.© 2026 · Made on Earth ✳