All formats

ImageSharp

LanguageC# (.NET 8 or later)
LicenseSix Labors Split License: Apache 2.0 for open source, non-profits and companies with under $1M annual revenue; commercial license otherwise
Repositorygithub.com/SixLabors/ImageSharp
Documentationdocs.sixlabors.com
Depends onnothing (pure managed code)
Read / writeyes / yes; baseline and progressive, 4:4:4 / 4:2:2 / 4:2:0, grayscale, CMYK and YCCK decoding; Exif, XMP, ICC, IPTC

ImageSharp decodes and encodes JPEG in managed C# with SIMD (System.Runtime.Intrinsics), so it runs on every platform .NET runs on with no native libraries to deploy. It also reads PNG, GIF, WebP, TIFF, BMP and more, and has a processing pipeline for resizing, cropping and color adjustments.

Its JPEG decoder is slower than libjpeg-turbo but fast enough for web servers. The encoder writes baseline or progressive files with optimized Huffman tables. Metadata (Exif, XMP, ICC, IPTC) is kept when you load and save. License note: the Six Labors Split License isn’t an OSI license for commercial users above the revenue limit.

Installation#

Shell
dotnet add package SixLabors.ImageSharp

Basic usage: resize a photo and save as JPEG#

C#
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

using Image image = Image.Load("in.jpg");
Console.WriteLine($"{image.Width} x {image.Height}");

image.Mutate(x => x
    .AutoOrient()          // apply the Exif orientation to the pixels
    .Resize(1200, 0));     // 0 = keep the aspect ratio

image.SaveAsJpeg("out.jpg", new JpegEncoder { Quality = 85 });

How to get JPEG dimensions without decoding#

Image.Identify reads only the headers:

C#
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;

ImageInfo info = Image.Identify("in.jpg");
JpegMetadata jpeg = info.Metadata.GetJpegMetadata();
Console.WriteLine($"{info.Width} x {info.Height}, {jpeg.ColorType}, progressive: {jpeg.Progressive}");

How to read Exif data (camera, date, orientation)#

C#
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;

ImageInfo info = Image.Identify("photo.jpg");
ExifProfile? exif = info.Metadata.ExifProfile;
if (exif != null)
{
    if (exif.TryGetValue(ExifTag.Model, out IExifValue<string>? model))
        Console.WriteLine($"Camera: {model.Value}");
    if (exif.TryGetValue(ExifTag.DateTimeOriginal, out IExifValue<string>? taken))
        Console.WriteLine($"Taken: {taken.Value}");
    if (exif.TryGetValue(ExifTag.Orientation, out IExifValue<ushort>? orientation))
        Console.WriteLine($"Orientation: {orientation.Value}");

    foreach (IExifValue value in exif.Values)   // every tag
        Console.WriteLine($"{value.Tag}: {value.GetValue()}");
}

How to write a progressive JPEG with 4:4:4 subsampling#

C#
var encoder = new JpegEncoder
{
    Quality = 90,
    Progressive = true,
    ColorType = JpegColorType.YCbCrRatio444,   // no chroma subsampling
};
image.SaveAsJpeg("out.jpg", encoder);

Other values: YCbCrRatio420 (default), YCbCrRatio422, Luminance (grayscale).

How to remove metadata before saving#

C#
image.Metadata.ExifProfile = null;
image.Metadata.XmpProfile = null;
image.Metadata.IptcProfile = null;
// keep image.Metadata.IccProfile unless you know the image is sRGB
image.SaveAsJpeg("clean.jpg");

How to convert PNG with transparency to JPEG#

JPEG has no alpha channel. Fill transparent areas with a background color first, or they turn black:

C#
using Image image = Image.Load("logo.png");
image.Mutate(x => x.BackgroundColor(Color.White));
image.SaveAsJpeg("logo.jpg", new JpegEncoder { Quality = 90 });

Tips#