Working with Images in C# (.NET): From Basics to Advanced Techniques
Image processing is one of the key tasks in modern development. In the C# (.NET) ecosystem, there are several powerful libraries for working with graphics, ranging from the built-in System.Drawing to modern cross-platform solutions such as ImageSharp and SkiaSharp. In this article, we will thoroughly examine the main approaches, provide code examples, and give practical recommendations.
1. Overview of Libraries for Working with Images in .NET
The choice of library depends on your tasks and platform. Here are three main options:
- System.Drawing.Common — a classic library from Microsoft, available in .NET 6+. It works via GDI+ on Windows but has limitations on Linux/macOS.
- SixLabors.ImageSharp — a fully managed, cross-platform library. Supports JPEG, PNG, BMP, GIF, WebP formats. Great for web applications and server-side processing.
- SkiaSharp — a wrapper over the Skia engine (used in Chrome, Flutter). Provides high performance and extensive capabilities for 2D graphics, including working with images, text, and vector graphics.
For most modern projects, ImageSharp is recommended — it is easy to use, actively developed, and platform-independent.
2. Installing and Adding Libraries
Installation via NuGet Package Manager (or .NET CLI):
// For ImageSharpdotnet add package SixLabors.ImageSharp
// For SkiaSharpdotnet add package SkiaSharp
// For System.Drawing (if needed)dotnet add package System.Drawing.Common3. Basic Image Operations Using ImageSharp
Let's look at the main operations: loading, resizing, cropping, applying filters, and saving.
3.1 Loading and Displaying Information
using SixLabors.ImageSharp;using SixLabors.ImageSharp.PixelFormats;
using (Image<Rgba32> image = Image.Load<Rgba32>("input.jpg")){ Console.WriteLine($"Width: {image.Width}, Height: {image.Height}"); Console.WriteLine($"Pixel format: {image.PixelType}");}3.2 Resizing While Maintaining Aspect Ratio
using SixLabors.ImageSharp.Processing;
using (Image<Rgba32> image = Image.Load<Rgba32>("input.jpg")){ int newWidth = 800; int newHeight = (int)((float)image.Height / image.Width * newWidth);
image.Mutate(x => x.Resize(newWidth, newHeight)); image.Save("output_resized.jpg");}3.3 Cropping the Center Part
using (Image<Rgba32> image = Image.Load<Rgba32>("input.jpg")){ int cropSize = Math.Min(image.Width, image.Height); var rect = new Rectangle( (image.Width - cropSize) / 2, (image.Height - cropSize) / 2, cropSize, cropSize );
image.Mutate(x => x.Crop(rect)); image.Save("output_cropped.jpg");}3.4 Applying Filters (Black and White, Blur)
using SixLabors.ImageSharp.Processing;using SixLabors.ImageSharp.Processing.Processors.Transforms;
using (Image<Rgba32> image = Image.Load<Rgba32>("input.jpg")){ // Black and white filter image.Mutate(x => x.Grayscale());
// Gaussian blur (radius 5) image.Mutate(x => x.GaussianBlur(5));
image.Save("output_filtered.jpg");}4. Working with Formats and Quality
ImageSharp allows you to set save parameters for each format:
using SixLabors.ImageSharp.Formats.Jpeg;
using (Image<Rgba32> image = Image.Load<Rgba32>("input.jpg")){ var encoder = new J