All formats

Magick.NET

LanguageC# (.NET Standard 2.0, .NET 8+)
LicenseApache-2.0 (ImageMagick license for the native part)
Repositorygithub.com/dlemstra/Magick.NET
DocumentationMagick.NET docs
Depends onnative ImageMagick with libheif, libde265 and libaom, included in the NuGet package
Read / writeyes / no (HEIC is read-only; AVIF can be written)

Magick.NET is the .NET wrapper of ImageMagick. Its NuGet packages include libheif with the libde265 HEVC decoder for Windows, Linux and macOS, so HEIC photos from phones open with no Windows extensions or system libraries. That makes it the simplest way to convert uploaded iPhone photos to JPEG on a server.

The bundled libheif has no HEVC encoder, so Magick.NET can’t write HEIC (MagickFormat.Heic reports SupportsWriting = false). It can write AVIF, which uses the same container with AV1. For writing HEIC from .NET use LibHeifSharp with a libheif that includes x265.

Installation#

Shell
dotnet add package Magick.NET-Q8-AnyCPU

Use Magick.NET-Q16-AnyCPU to keep the full precision of 10-bit HEIC images.

Basic usage: convert HEIC to JPEG#

C#
using ImageMagick;

using var image = new MagickImage("IMG_0001.heic");
Console.WriteLine($"{image.Width} x {image.Height}");
image.AutoOrient();     // apply the stored rotation
image.Quality = 90;
image.Write("IMG_0001.jpg");

How to read Exif data from a HEIC photo#

C#
using var image = new MagickImage("IMG_0001.heic");
var exif = image.GetExifProfile();
if (exif != null)
{
    var model = exif.GetValue(ExifTag.Model);
    var date = exif.GetValue(ExifTag.DateTimeOriginal);
    Console.WriteLine($"{model?.Value} {date?.Value}");
}

How to get HEIC dimensions without decoding#

C#
var info = new MagickImageInfo("IMG_0001.heic");
Console.WriteLine($"{info.Width} x {info.Height}");

How to make a thumbnail of a HEIC photo#

C#
using var image = new MagickImage("IMG_0001.heic");
image.AutoOrient();
image.Thumbnail(new MagickGeometry(400, 400));  // fit in 400 x 400, strips metadata
image.Write("thumb.jpg");

How to read only the primary image#

A HEIC file can contain several top-level images (bursts, edited versions), and the primary image isn’t always the first. To read just the primary one:

C#
var settings = new MagickReadSettings();
settings.SetDefine(MagickFormat.Heic, "primary-image", "true");
using var image = new MagickImage("IMG_0001.heic", settings);

How to convert HEIC from a stream (e.g. an upload)#

C#
using var image = new MagickImage(uploadStream);  // format is detected from the content
image.AutoOrient();
image.Format = MagickFormat.Jpeg;
image.Quality = 85;
image.Write(outputStream);

Tips#